{***************************************************************
    SpyGestion  Copyright (C) 2008 Christophe KOALI <nature2gas@gmail.com>
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
****************************************************************}
unit uMain;

interface



// f := x-> (2000 / (1 + x)) * 1.44;


(*
http://groups.google.fr/group/borland.public.delphi.ide.general/browse_thread/thread/17c5db3181961557/40d5d531150f4548?lnk=st&q=CTRL++%2B+CLick+Delphi+2006&rnum=6&hl=fr#40d5d531150f4548


Can someone please tell me if I screwed up my delphi or is delphi
screwed up ;)

When I see function myclass.a(1, 'a') or whatever that someone wrote, I
want to see the
function.  Sometimes the above methods work quick, sometimes delphi
"thinks" about it, then ignores the horrible request and drinks some
coffee, and sometimes delphi completely ignores the request to see the
code as if to say "you really think I'm gonna do that?"

So, what's the way to tame the IDE so that it always goes to the code
implementation or declaration (or at least the file).  The code is all
with debug mode, and <ctrl><enter> on a used file goes to the file, so
what's the error I'm making???

Thanks!

En résumé: Il faut activer les informations de débogage pour pouvoir
utiliser le CTRL + Click
*)



uses
  Windows, Messages, SysUtils,  Classes, Graphics, Controls, Forms,
  Dialogs, Grids, BaseGrid,
  AdvGrid, StdCtrls,
  ESBDates,
  asgspin,
  //modColoration,
  modLanguageParsing,

  modParsingClassIStatistiques,

  
  modSimpleRemplace,
  modUnitAndDefInfos,
  Math,
  modLibSocket,
  modFlotteEnVoyage,

  modMessagesList,
  modPlanete,
  modRapport,
  modBaseDeDonnesRapport,

  modGalaxiePlanetes,

  modSondesAttaque,
  modCore,
  modBaseType,
  modApercuMsg,

  modStatsPlayers,
  modStatsGetRecent,
  modStatsGetAlliance,
  modFlotteVaisseauxChoix,

  modClasses,
  modRegistre, 
  modProfilsForAttack,

  modLinkOtherPlanet,
  modParsingClass,
  modSondageList,
  modActionManager,

  modInteractionWeb,
  modLangGetList,
  modLocalSettings,
  modInteractionFichierUpdate,

  modAlarmeAttaque,
  modConstantes,
  HttpProt,
  modTunnelGestion,
  modParsingClassIApercu,

  modTunnelSessionId,
  sFonctionsChaines,  ShellApi,
  Clipbrd,
  modGIDtoSTR, Spin, ComCtrls, Buttons, ExtCtrls,
  Menus, BarMenus, hhCheckBox,
  GradientLabel, ScruteX, TransparentPanel,  WSocket, WSocketS,
  IdBaseComponent,
  modNewsGestion,
  sHTMLFonctions,
  modMd5,
  modCookies,
  ProxyInfo,

  //modTranslationInterface,
  modTemplateMotor,
  modTunnelTemplate,
  modTemplateTabDraw,

  modSound,
  modSoundGest,
  fmod,
  fmodtypes,
  modFormulesDuJeu,

  gnugettext,
  modCoreRecu,

  modSockUtils,

  modInteractionAuteur,
  modPopupAdv,
  modBoardLittleMotor,


  modFlotteTracking,
  
  modListeAttaqueCollection,
  modListeAttaqueVaisseauxInfos,
  
   AdvTabSet, BcDrawModule,
   modInteractionKey,
   modSGrid,
   modClassRessources,

   L01_modPlayerUtils,
   L35_modEvacuationAuto,
   L40_modPowerClasses,


   modPlayerFinal,
   modSGridGestion,

   frmCdRMonitor,

   WinSock,
   modIRCGlobal,
   modIRCMyAdvClient,
   modIRCGestionNoColl,
   modIRCGestion,
   modIRCInterface,

   modParsingClassBase,

   
   Commctrl,
  BcCustomDrawModule, CheckLst, JvComponentBase, JvBalloonHint;

(* pour le TValueListEditor:
http://www.developpez.net/forums/viewtopic.php?t=227390
Il fallait effectivement utiliser l'événement onDrawCell, comme ceci :
Code:
procedure TForm1.vlDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
begin
  if ARow = 2 then
    vl.Canvas.Font.Color := clRed
  else
    vl.Canvas.Font.Color := clBlack;

  if ACol = 0 then
    vl.Canvas.TextOut( Rect.Left, Rect.Top, vl.Keys[ARow] )
  else
    vl.Canvas.TextOut( Rect.Left, Rect.Top, vl.Values[vl.Keys[ARow]] );

end;

SAUF QUE : TRÈS IMPORTANT!!!
Mettre la propriété Default Drawing du TValueListEditor à false, sinon les
couleurs par défaut sont tout de même affichées.
Aussi, ceci ne change que la couleur du texte dans les cellules, vous aurez
peut-être quelques modifications à apporter dans le code d'affichage tout dépendant
des résultats que vous voulez obtenir.
*)

const
   CNT_ERRROR_DB_INVALID = -9998;
   
   CONF_GIDTOSTRDEFAULT = 'gidstr.txt';



const
   REG_PROG_NAME         = 'AttackGest';
   REG_PROG_SECTION_CFG  = 'general';

   REG_KEY_LASTPROFILLOADED  = 'LastProfilFile';


   WM_TASKABAREVENT    = WM_USER + 1;
   WM_OPERATION_CODE   = WM_USER + 2;



 //  REG_KEY_LOADPROFIL_AT_STARTUP = 'AutoLoadProfil';
 //  REG_KEY_LOADGALAXIE_AUTO = 'AutoLoadGalaxie';
   //REG_KEY_LAUNCH_SERVER_AT_STARTUP = 'LaunchServerAtStartup';
 //  REG_KEY_SAVE_WEB_PAGES = 'SaveWebPages';


   //APP_CAPTION = 'Historique des rapports';
   APP_CAPTION = 'OGame Spider';





   SONDAGE_INTERVAL_DURING_SONDAGE = 6000;
   SONDAGE_INTERVAL_DURING_SONDAGE_FAST = 1700;
   SONDAGE_INTERVAL_QUAND_PLUSRIENASONDER = 30000;
   SONDAGE_INTERVAL_QUAND_FLOTTEMAXIATTEINT = 15000;

   WM_MISC_ADDED = 99;
   WM_CLOSE_MISC = WM_CLOSE + WM_MISC_ADDED;


   CNT_CRLF = #$0D#$0A;

   // La galaxie depend du profil, il y en a une par profil donc
   //REG_LASTGALAXIELOADED = 'LastGalaxieLoaded';

const

   CNT_TITLE_TRAYICON = 'Spy Gestion';


type

  TFichierBDDType = (tbdRapports, tbdGalaxie);


  TThreadVerifExp = class(TThread)
  private

  public



  end;

  TfrmRapportHistorique = class(TForm)
    pcSwitch: TPageControl;
    TabSheet1: TTabSheet;
    tabBaseDeDonnees: TTabSheet;
    cmdDbLoad: TButton;
    cmdDbSave: TButton;
    gbPlanete: TGroupBox;
    txtRapportLast: TMemo;
    seNbAttaque: TSpinEdit;
    cmdUpdatePlanete: TButton;
    Label3: TLabel;
    seNbSondage: TSpinEdit;
    Label4: TLabel;
    txtInfos: TMemo;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    sePointsMax: TSpinEdit;
    SpinEdit1: TSpinEdit;
    lstFilesDB: TListBox;
    Label5: TLabel;
    txtNewBDD: TEdit;
    Label6: TLabel;
    cmdCreateDBUseIt: TButton;
    cmdAddAttackNow: TSpeedButton;
    timMonitorClipboard: TTimer;
    popRapport: TBcBarPopupMenu;
    PopupTray: TBcBarPopupMenu;
    Copier1: TMenuItem;
    cmdStatsLoad: TButton;
    Label7: TLabel;
    seCurrPlayerPoints: TSpinEdit;
    Label8: TLabel;
    cmdTest: TButton;
    pcUniversRapports: TPageControl;
    TabSheet6: TTabSheet;
    sgPlanetesRecentes: TAdvStringGrid;
    cmdBDDUpgradeV2toV3: TButton;
    chkTropBienDef: ThhCheckBox;
    chkNivEspEleve: ThhCheckBox;
    chkNeJamaisAttaquer: ThhCheckBox;
    chkPouleAuxOeufsDor: ThhCheckBox;
    popDureeRecent: TBcBarPopupMenu;
    N1heure1: TMenuItem;
    N2heure1: TMenuItem;
    N3heure1: TMenuItem;
    N5heures1: TMenuItem;
    N8heures1: TMenuItem;
    N12heures1: TMenuItem;
    N1jour1: TMenuItem;
    N2jours1: TMenuItem;
    N4jours1: TMenuItem;
    tabOutils: TTabSheet;
    tabProfilsEdit: TTabSheet;
    seStatsUni: TSpinEdit;
    lblProfilActuel: TGradientLabel;
    scanDir: TScruteDossier;
    chkTropPeuDev: ThhCheckBox;
    TabSheet7: TTabSheet;
    sgPlanetesPoulesDor: TAdvStringGrid;
    menuTopMain: TBcBarMainMenu;
    Fichier1: TMenuItem;
    Quitter1: TMenuItem;
    Divers1: TMenuItem;
    Dsactiverlacaptureautomatiquedesrapports1: TMenuItem;
    menCaptureRapportActiver: TMenuItem;
    menCaptureRapportDesactiver: TMenuItem;
    Sauvegarder1: TMenuItem;
    N1: TMenuItem;
    Dure1: TMenuItem;
    menDureeRecent2h: TMenuItem;
    menDureeRecent3h: TMenuItem;
    menDureeRecent5h: TMenuItem;
    menDureeRecent10h: TMenuItem;
    menDureeRecent1j: TMenuItem;
    menDureeRecent2j: TMenuItem;
    menDureeRecent1h: TMenuItem;
    Profil1: TMenuItem;
    menSpiderLogin: TMenuItem;
    Logout1: TMenuItem;
    tabSystemSolaire: TTabSheet;
    TransparentPanel2: TTransparentPanel;
    seSystemSolairChoix: TSpinEdit;
    TabSheet11: TTabSheet;
    GroupBox8: TGroupBox;
    txtSpiderGalaxieScanFile: TEdit;
    lblGalaxieScanFichier: TLabel;
    lblGalaxieScanGalaxie: TLabel;
    seGalaxieSystemeStart: TSpinEdit;
    seGalaxieSystemeEnd: TSpinEdit;
    Label45: TLabel;
    lblGalaxieScanSystemes: TLabel;
    popSpiderGalaxieScanRange: TBcBarPopupMenu;
    menGalaxieSetRangeScan: TMenuItem;
    N30systmes1: TMenuItem;
    N40systmes1: TMenuItem;
    N50systmes1: TMenuItem;
    N60systmes1: TMenuItem;
    N70systmes1: TMenuItem;
    N80systmes1: TMenuItem;
    N90systmes1: TMenuItem;
    N100systmes1: TMenuItem;
    GroupBox9: TGroupBox;
    chkSpiderStatsGlobales: ThhCheckBox;
    chkSpiderStatsFlottes: ThhCheckBox;
    chkSpiderStatsRecherche: ThhCheckBox;
    chkSpiderStatsDateUnixAbrege: ThhCheckBox;
    cmdSpiderGalaxieScan: TButton;
    cmdSpiderGalaxieStop: TButton;
    cmdSpiderStatsStop: TButton;
    cmdSpiderStatsScan: TButton;
    txtDebug1: TMemo;
    Label18: TLabel;
    seSpiderGalaxieDureeRecent: TSpinEdit;
    lblGalaxieScanDuree: TLabel;
    tabEspionnage: TTabSheet;
    gdSystemSolaire: TAdvStringGrid;
    pcEspionnage: TPageControl;
    tabEspionnageIn: TTabSheet;
    TabSheet13: TTabSheet;
    GroupBox10: TGroupBox;
    lblSpiderGalaxieScan: TLabel;
    cmdSondageInactifs: TButton;
    gbSondagePoints: TGroupBox;
    Label53: TLabel;
    seSondageStatsLimitGlobales: TSpinEdit;
    Label54: TLabel;
    lblScanUserPointsGlobaux: TLabel;
    Label56: TLabel;
    Label57: TLabel;
    seSondageStatsLimitFlottes: TSpinEdit;
    Label58: TLabel;
    lblScanUserPointsFlottes: TLabel;
    Label60: TLabel;
    RadioButton1: TRadioButton;
    optAttaqueOR: TRadioButton;
    cmdSondagePoints: TButton;
    GroupBox12: TGroupBox;
    seSondageSystemStart: TSpinEdit;
    seSondageSystemEnd: TSpinEdit;
    Label50: TLabel;
    seSondageDureePourEtrePrisEnCompte: TSpinEdit;
    Label52: TLabel;
    Label49: TLabel;
    Label51: TLabel;
    lblSondageGalaxie: TLabel;
    chkSondageInactif2sm: ThhCheckBox;
    chkSondageInactif4sm: ThhCheckBox;
    chkSondagePointGlobalNonClasse: ThhCheckBox;
    chkSondagePointFlottesNonClasse: ThhCheckBox;
    sgSondages: TAdvStringGrid;
    Label61: TLabel;
    cbSondagePlanete: TComboBox;
    cmdSondageStart: TButton;
    cmdSondageStop: TButton;
    cmdSondageClearAll: TButton;
    timSondage: TTimer;
    popDureeRecentForGalaxie: TBcBarPopupMenu;
    menGalaxieChangeDelay: TMenuItem;
    menGalaxieChangeDelay2j: TMenuItem;
    menGalaxieChangeDelay3j: TMenuItem;
    menGalaxieChangeDelay4j: TMenuItem;
    menGalaxieChangeDelay7j: TMenuItem;
    menGalaxieChangeDelay6h: TMenuItem;
    menGalaxieChangeDelay12h: TMenuItem;
    cmdSondageUpdateSGrid: TButton;
    cmdSondageUpdateDateOnly: TButton;
    tabAttaque: TTabSheet;
    Label55: TLabel;
    cmdAttaqueDoIt: TButton;
    sgVaisseaux: TAdvStringGrid;
    gpClibleaAttaques: TGroupBox;
    seAttaquePosition: TSpinEdit;
    seAttaqueSystem: TSpinEdit;
    seAttaqueGalaxie: TSpinEdit;
    Label59: TLabel;
    Label62: TLabel;
    lblAttaqueStatsGlobales: TLabel;
    lblAttaqueStatsFlottes: TLabel;
    Label65: TLabel;
    lblAttaqueJoueur: TLabel;
    Label67: TLabel;
    Label68: TLabel;
    lblAttaqueNomPlanete: TLabel;
    popPlaneteListRapport: TBcBarPopupMenu;
    menEspionner: TMenuItem;
    menVoirSystmeSolaire: TMenuItem;
    menAttaquer: TMenuItem;
    N3: TMenuItem;
    cmdMessageListGet: TButton;
    seSondageIgnoreDelayLastSondage: TSpinEdit;
    Label72: TLabel;
    lblCurrentUnivers: TLabel;
    lblCurrentGalaxie: TLabel;
    Label74: TLabel;
    cbGalaxieScanPlanete: TComboBox;
    lblGalaxieScanPlanetes: TLabel;
    cbAttaquePlanete: TComboBox;
    Label73: TLabel;
    cmdChangePlaneteAndUpdateVaisseauxList: TButton;
    lblStatusAttaque: TLabel;
    lblAttaqueAlliance: TLabel;
    Label64: TLabel;
    cmdViewAppercuListMsg: TButton;
    sgGridFlotteList: TAdvStringGrid;
    Label63: TLabel;
    lblAttaqueAllianceBestStats: TLabel;
    Label69: TLabel;
    lblAttaqueAllianceMoyenne: TLabel;
    chkSondageStatsExclureInactif: ThhCheckBox;
    gbAttaqueRapport: TGroupBox;
    Label66: TLabel;
    lblAttaqueMetal: TLabel;
    lblAttaqueCristal: TLabel;
    Label77: TLabel;
    Label78: TLabel;
    lblAttaqueDeuterium: TLabel;
    lblAttaqueGT: TLabel;
    Label81: TLabel;
    lblAttaqueValidite: TLabel;
    Label76: TLabel;
    lblAttaqueFlotte: TLabel;
    lblAttaqueDefense: TLabel;
    Label80: TLabel;
    Label82: TLabel;
    TabSheet4: TTabSheet;
    sgFiltrer: TAdvStringGrid;
    N5: TMenuItem;
    menVoirAncienRapport: TMenuItem;
    Filtre1: TMenuItem;
    Poulesauxoeufsdor1: TMenuItem;
    ropbiendfendu1: TMenuItem;
    Nejamaisattaquer1: TMenuItem;
    Niveauespionnagelev1: TMenuItem;
    roppeudevellop1: TMenuItem;
    Inactif1: TMenuItem;
    Modevacances1: TMenuItem;
    Protectiondesnewbz1: TMenuItem;
    Sansflags1: TMenuItem;
    menFlagTropBienDefIncl: TMenuItem;
    menFlagTropBienDefExcl: TMenuItem;
    menFlagNivEspEleveIncl: TMenuItem;
    menFlagNivEspEleveExcl: TMenuItem;
    menFlagNeJamaisAttackIncl: TMenuItem;
    menFlagNeJamaisAttackExcl: TMenuItem;
    menFlagPouleDorIncl: TMenuItem;
    menFlagPouleDorExcl: TMenuItem;
    menFlagTropPeuDevIncl: TMenuItem;
    menFlagTropPeuDevExcl: TMenuItem;
    menFlagAucunIncl: TMenuItem;
    menFlagAucunExcl: TMenuItem;
    N6: TMenuItem;
    menFlagTropBienDefIgnr: TMenuItem;
    N7: TMenuItem;
    menFlagNivEspEleveIgnr: TMenuItem;
    N8: TMenuItem;
    menFlagNeJamaisAttackIgnr: TMenuItem;
    N9: TMenuItem;
    menFlagPouleDorIgnr: TMenuItem;
    N10: TMenuItem;
    menFlagTropPeuDevIgnr: TMenuItem;
    ousleslments1: TMenuItem;
    menFiltreTousElementPresent: TMenuItem;
    menFiltreTousElementNonPresent: TMenuItem;
    N11: TMenuItem;
    N12: TMenuItem;
    menFlagInactifIncl: TMenuItem;
    menFlagVacancesIncl: TMenuItem;
    menFlagNewbzIncl: TMenuItem;
    menFlagInactifExcl: TMenuItem;
    N13: TMenuItem;
    menFlagVacancesExcl: TMenuItem;
    N14: TMenuItem;
    menFlagNewbzExcl: TMenuItem;
    N15: TMenuItem;
    menFlagInactifIgnr: TMenuItem;
    menFlagVacancesIgnr: TMenuItem;
    menFlagNewbzIgnr: TMenuItem;
    N16: TMenuItem;
    Mthode1: TMenuItem;
    menFiltreToutesConditionsRemplies: TMenuItem;
    menFiltreAuMoinsUneCondRemplie: TMenuItem;
    Plantedtruite1: TMenuItem;
    menFlagPlaneteDetruiteIncl: TMenuItem;
    menFlagPlaneteDetruiteExcl: TMenuItem;
    N17: TMenuItem;
    menFlagPlaneteDetruiteIgnr: TMenuItem;
    Joueursbloqus1: TMenuItem;
    menFlagJoueurBloqueIncl: TMenuItem;
    menFlagJoueurBloqueExcl: TMenuItem;
    N18: TMenuItem;
    menFlagJoueurBloqueIgnr: TMenuItem;
    Listeactuelle1: TMenuItem;
    menFiltreTirerParGT: TMenuItem;
    menFiltreTrierParDate: TMenuItem;
    Label86: TLabel;
    N20: TMenuItem;
    html1: TMenuItem;
    timLoadLastDBAuto: TTimer;
    tabWebService: TTabSheet;
    TabSheet8: TTabSheet;
    menStatsAlliance: TMenuItem;
    Rcents1: TMenuItem;
    rierpar1: TMenuItem;
    menRecentsTrieGT: TMenuItem;
    menRecentsTrieFlotte: TMenuItem;
    menRecentsTrieLastAttaque: TMenuItem;
    chkSonderEnsuiteLesInactifs: ThhCheckBox;
    TabSheet2: TTabSheet;
    menFiltreTrierParDateAttaque: TMenuItem;
    menFiltreTrierParFlotte: TMenuItem;
    gsPlanet: TAdvStringGrid;
    menMettreAJourLempire: TMenuItem;
    lblAttaqueDeutDisponible: TLabel;
    lblAttaqueTrajetDuree: TLabel;
    Label92: TLabel;
    Label91: TLabel;
    lblAttaqueTrajetConsomation: TLabel;
    timServiceDelayCmd: TTimer;
    chkSondageFast: ThhCheckBox;
    Recycleurs1: TMenuItem;
    rierparrecycleurs1: TMenuItem;
    N21: TMenuItem;
    Arrteroperationencours1: TMenuItem;
    Label97: TLabel;
    cbAttaqueSpeedRatio: TComboBox;
    chkSondageEssaiMultiple: ThhCheckBox;
    Label98: TLabel;
    lblAttaqueTrajetRecycleur: TLabel;
    Label90: TLabel;
    lblAttaqueDistance: TLabel;
    Label99: TLabel;
    lblNbRecycleurOwnFlotte: TLabel;
    Label100: TLabel;
    lblRecyclagePointsPerdus: TLabel;
    lblStatusAttaque2: TLabel;
    cmdFlotteAttaqueRefreshDate: TButton;
    cmdSpiderEffacerMsgDebug: TButton;
    cmdAttackWithPT: TButton;
    hhCheckBox3: ThhCheckBox;
    N19: TMenuItem;
    N22: TMenuItem;
    menRecentAttaqueAuto: TMenuItem;
    chkAttackWithPT: ThhCheckBox;
    chkAttackInclureCroiseur: ThhCheckBox;
    chkNePasSonderPourCetteSession: ThhCheckBox;
    seSondageMinRecycleurs: TSpinEdit;
    chkSondageMinRecycleur: ThhCheckBox;
    popSondageList: TBcBarPopupMenu;
    menSondageEnlever: TMenuItem;
    menStatsAllianceSondage: TMenuItem;
    Voirsystmesolaire1: TMenuItem;
    N23: TMenuItem;
    chkSondageDontAddDejaAttack: ThhCheckBox;
    menRecentsDefenses: TMenuItem;
    GroupBox15: TGroupBox;
    txtSondageAllianceOrJoueur: TEdit;
    cmdSondageAlliance: TButton;
    cmdSondageJoueur: TButton;
    hhCheckBox4: ThhCheckBox;
    chkSonderLesAllies: ThhCheckBox;
    chkSondageNePasFaireDispNotifWindow: ThhCheckBox;
    chkPlaneteARecycler: ThhCheckBox;
    chkPlaneteDejaRecycler: ThhCheckBox;
    menEspionnerSesPlantes: TMenuItem;
    TabSheet3: TTabSheet;
    cmdSondageResetDate: TButton;
    chkAddOnlyKnowEtSansDef: ThhCheckBox;
    chkSondageDontAddDejaAttack24h: ThhCheckBox;
    chkSondageMinPT: ThhCheckBox;
    seSondageMinPT: TSpinEdit;
    chkSondageDontAddDejaAttack2h: ThhCheckBox;
    chkSondageDontAddDejaAttack12h: ThhCheckBox;
    chkSondageDontSondeNivEspEleve: ThhCheckBox;
    cmdSpiderVueGenerale: TButton;
    chkSondageMaxDefScore: ThhCheckBox;
    seSondageMaxScoreDef: TSpinEdit;
    cmdSondeAttackReativeBoutonSondage: TButton;
    chkDontSondeDejaRecycler: ThhCheckBox;
    pcProfil: TPageControl;
    tabProfilGeneral: TTabSheet;
    TabSheet15: TTabSheet;
    gbBaseDeDonnees: TGroupBox;
    Label22: TLabel;
    seDBGalaxie: TSpinEdit;
    cmdLoadDBFromProfils: TButton;
    GroupBox6: TGroupBox;
    lblProfilFichierRapportDB: TLabel;
    Label26: TLabel;
    Label24: TLabel;
    lblNbPlanetesLoaded: TLabel;
    GroupBox7: TGroupBox;
    lblProfilFichierGalaxyDB: TLabel;
    Label39: TLabel;
    Label40: TLabel;
    lblNbPlaneteLoadedGalaxy: TLabel;
    gbStatistiques: TGroupBox;
    Label19: TLabel;
    Label20: TLabel;
    Label21: TLabel;
    lblStatsEtatGlobales: TLabel;
    lblStatsEtatFlottes: TLabel;
    lblStatsEtatRecherche: TLabel;
    Label38: TLabel;
    txtStatsUnivers: TLabel;
    cmdStatsReload: TButton;
    GroupBox5: TGroupBox;
    Label9: TLabel;
    Label12: TLabel;
    Label11: TLabel;
    seDureeForRecent: TSpinEdit;
    cmdAppliqueAnciennetes: TButton;
    cmdClipboardSwitch: TButton;
    chkDesactiveColonneDef: ThhCheckBox;
    popGalaxie: TBcBarPopupMenu;
    menSystemSolaireSpy: TMenuItem;
    menSystemSolaireStatsAlliance: TMenuItem;
    N24: TMenuItem;
    menSystemSolaireAttack: TMenuItem;
    menFiltreTrierParCoords: TMenuItem;
    menRecentsCoords: TMenuItem;
    chkDisableSecuSondage: ThhCheckBox;
    Divers2: TMenuItem;
    HTMLmodeguerre1: TMenuItem;
    cmdSondeAttaqueEffacerDejaSonde: TButton;
    chkSondageMaxPT: ThhCheckBox;
    seSondageMaxPT: TSpinEdit;
    cmdSondageClearNonSonde: TButton;
    cmdAlerteAttDebug: TButton;
    timSondeAttackVague: TTimer;
    cmdNextVague3: TButton;
    chkSondageDoDateVerifForRapportToo: ThhCheckBox;
    menFairedisparaitre: TMenuItem;
    N25: TMenuItem;
    Minimiser1: TMenuItem;
    N26: TMenuItem;
    menTrayIconDelete: TMenuItem;
    GroupBox2: TGroupBox;
    lblProxySpiderInfos: TLabel;
    lblProxySpiderInfoActive: TLabel;
    lblProxyIdent: TLabel;
    GroupBox3: TGroupBox;
    Label16: TLabel;
    Label36: TLabel;
    Label41: TLabel;
    seTunnelPort: TSpinEdit;
    txtTunnelRootUser: TEdit;
    txtTunnelRootPass: TEdit;
    cmdTunnelLancer: TButton;
    chkTunnelLancerAuDem: ThhCheckBox;
    wssTunnel: TWSocketServer;
    lblFlotteScore: TLabel;
    Label108: TLabel;
    tabInformations: TTabSheet;
    pcInformations: TPageControl;
    tabNews: TTabSheet;
    tabEcrireAuteur: TTabSheet;
    Memo1: TMemo;
    Label94: TLabel;
    txtNewsAffichage: TMemo;
    cmdInfosDLNews: TButton;
    tabEcrireAuteurConfig: TTabSheet;
    cmdContactEnvoi: TButton;
    Label161: TLabel;
    cmdNewsPrecedente: TButton;
    cmdNewsSuivante: TButton;
    cmdNewsLaPlusRecente: TButton;
    Label159: TLabel;
    lblNewsNbNonLue: TLabel;
    gbInformationsProxy: TGroupBox;
    Label160: TLabel;
    Label162: TLabel;
    Label163: TLabel;
    Label164: TLabel;
    Label165: TLabel;
    txtInfosProxyHost: TEdit;
    seInfosProxyPort: TSpinEdit;
    chkInfosProxyUse: ThhCheckBox;
    cbInfosProxyType: TComboBox;
    txtInfosProxyUsername: TEdit;
    txtInfosProxyPassword: TEdit;
    hhCheckBox17: ThhCheckBox;
    cmdViewAttack: TButton;
    seAttackInclureCroiseurs: TSpinEdit;
    Label43: TLabel;
    tabConstruction: TTabSheet;
    timAttackNotificationAndOnTimer: TTimer;
    chkSondageEmettreBeepAtEnd: ThhCheckBox;
    chkSondageLireMsgAtEnd: ThhCheckBox;
    pcConstruction: TPageControl;
    tabTempPlanete: TTabSheet;
    sgElementsConstructible: TAdvStringGrid;
    tabConstructionRessources: TTabSheet;
    sgRessourcesProd: TAdvStringGrid;
    TabSheet24: TTabSheet;
    sgElementsAction: TAdvStringGrid;
    TransparentPanel1: TTransparentPanel;
    cmdPlanetActProdInserer: TButton;
    optPlanetActProdDeut: TRadioButton;
    optPlanetActProdCristal: TRadioButton;
    optPlanetActProdMetal: TRadioButton;
    optPlanetActProdBest: TRadioButton;
    optPlanetActProdDontChange: TRadioButton;
    switchPlanet: TAdvTabSet;
    cmdTunnelStop: TButton;
    Memo2: TMemo;
    Label44: TLabel;
    Label23: TLabel;
    GroupBox27: TGroupBox;
    Label95: TLabel;
    Label96: TLabel;
    txtForumUsername: TEdit;
    txtForumPassword: TEdit;
    Label48: TLabel;
    chkTunnelRestreindreLocal: ThhCheckBox;
    txtTunnelURL: TEdit;
    Label33: TLabel;
    cmdTunnelGo: TButton;
    memHelp: TMemo;
    timAdditionnal: TTimer;
    chkTunnelDesactiveCompressionIE: ThhCheckBox;
    Lunes1: TMenuItem;
    menFiltresLuneInclure: TMenuItem;
    menFiltresLuneExclure: TMenuItem;
    chkAttaqueLune: ThhCheckBox;
    chkSondageInclureLune: ThhCheckBox;
    chkSondageAddOnlyLune: ThhCheckBox;
    menFiltresLuneAfficheOnly: TMenuItem;
    N2: TMenuItem;
    menExporterempire1: TMenuItem;
    menSondageEnleverJoueur: TMenuItem;
    menSondageEnleverAlliance: TMenuItem;
    GroupBox4: TGroupBox;
    chkTunnelUseRewritingRules: ThhCheckBox;
    chkTunnelUseJsEtCssLocaux: ThhCheckBox;
    chkTunnelInterdirePageLogout: ThhCheckBox;
    Label88: TLabel;
    chkTunnelInterdirePageListeDamis: ThhCheckBox;
    chkTunnelInterdirePageRecherche: ThhCheckBox;
    chkTunnelInterdirePageAlliance: ThhCheckBox;
    chkTunnelInterdirePageEcritureMsg: ThhCheckBox;
    chkTunnelInterdirePageSupprMsg: ThhCheckBox;
    menLanguage: TMenuItem;
    menuMainDrawModule: TBcCustomDrawModule;
    GroupBox16: TGroupBox;
    Button1: TButton;
    Button2: TButton;
    Button4: TButton;
    Button6: TButton;
    cmdConstructionMaj: TButton;
    lblCurrPlaneteCoord: TLabel;
    lblPreventConstruction: TLabel;
    TabSheet26: TTabSheet;
    memConstructions: TMemo;
    chkActiveModuleGestionAuto: ThhCheckBox;
    Label10: TLabel;
    popPlaneteActionScript: TBcBarPopupMenu;
    menActionMonter: TMenuItem;
    menActionDescendre: TMenuItem;
    menActionMettreEnHaut: TMenuItem;
    menActionMettreEnBas: TMenuItem;
    MenuItem1: TMenuItem;
    menActionEnlever: TMenuItem;
    MenuItem2: TMenuItem;
    menActionToutEffacer: TMenuItem;
    Label173: TLabel;
    cmdRessourcesUpdate: TButton;
    cmdRessourceCalculer: TButton;
    popConstruction: TBcBarPopupMenu;
    menConstructionVoirOptimisation: TMenuItem;
    TabSheet14: TTabSheet;
    popMesPlanetes: TBcBarPopupMenu;
    popFlotteListMvt: TBcBarPopupMenu;
    memFlotteListEspionner: TMenuItem;
    Listesdesplantes1: TMenuItem;
    memFlotteListCoord: TMenuItem;
    cmdTrackingDebug: TButton;
    menFlotteListRetour: TMenuItem;
    cmdTestEva: TButton;
    N4: TMenuItem;
    menAjouterListeDattaque: TMenuItem;
    menRecentSuppriFlagTropPeuDev: TMenuItem;
    PageControl2: TPageControl;
    TabSheet27: TTabSheet;
    TabSheet28: TTabSheet;
    sgListeAttaque: TAdvStringGrid;
    GroupBox23: TGroupBox;
    GroupBox28: TGroupBox;
    cbListAttaquePlaneteSondage: TComboBox;
    Label106: TLabel;
    chkLASondageAvantAttackActive: ThhCheckBox;
    GroupBox29: TGroupBox;
    Label158: TLabel;
    cbListAttaquePlaneteDepart: TComboBox;
    chkLAVersionPT: ThhCheckBox;
    chkLAInclureCroiseurs: ThhCheckBox;
    seLANbCroiseurs: TSpinEdit;
    Label180: TLabel;
    Label181: TLabel;
    seLANbVB: TSpinEdit;
    chkLAInclureVB: ThhCheckBox;
    GroupBox30: TGroupBox;
    chkListeDattenteTraitementActive: ThhCheckBox;
    seLANbFreeSlot: TSpinEdit;
    Label182: TLabel;
    Label183: TLabel;
    cmdListeAttaqueUpdateList: TButton;
    cmdListeDAttaqueDebug: TButton;
    GroupBox31: TGroupBox;
    chkRecalculVaisseauxAvantAttaque: ThhCheckBox;
    seLAPartieDecimale: TSpinEdit;
    Label184: TLabel;
    Label185: TLabel;
    Label186: TLabel;
    Label187: TLabel;
    seLAVaisseauxSuppl: TSpinEdit;
    Label188: TLabel;
    chkLAMettreAJourDateAttaque: ThhCheckBox;
    cmdLAVider: TButton;
    TabSheet29: TTabSheet;
    cmdLAAjouterRecent: TButton;
    seAttackListCibleMax: TSpinEdit;
    seAttackListScoreDefMax: TSpinEdit;
    Label189: TLabel;
    seAttackListReclMax: TSpinEdit;
    Label190: TLabel;
    chkTunnelInterdirePageSupprColonies: ThhCheckBox;
    menChangerdeprofil1: TMenuItem;
    N27: TMenuItem;
    Label47: TLabel;
    pcOutils: TPageControl;
    tabOutilsPlanetes: TTabSheet;
    tabOutilsStatistiques: TTabSheet;
    gdStats: TAdvStringGrid;
    gdStats2: TAdvStringGrid;
    cmdScanAlliance2: TButton;
    txtAlliance2: TEdit;
    lblStatsAlliance2: TLabel;
    cmdStatsChercheFromUID: TButton;
    txtStatsUID: TEdit;
    cmdScanAlliance: TButton;
    txtAlliance: TEdit;
    lblStatsAlliance1: TLabel;
    gbExportSQL: TGroupBox;
    lblPlaneteExportTable: TLabel;
    lblPlaneteExportUserID: TLabel;
    txtOSpyUserID: TEdit;
    txtOSpyDB: TEdit;
    cmdExportSQL: TButton;
    optExportSQLInsert: TRadioButton;
    optExportSQLUpdate: TRadioButton;
    cmdExportStop: TButton;
    chkExportFichier: ThhCheckBox;
    Panel1: TPanel;
    optExportOGSpy: TRadioButton;
    optExportGalaxyTool: TRadioButton;
    optExportOGSpy302: TRadioButton;
    optExportSQLReplace: TRadioButton;
    chkExportUseUniformDate: ThhCheckBox;
    cmdGalaxieRecherchePlaneteVide: TButton;
    cmdVoirPlaneteInexistante: TButton;
    chkHTMLText: ThhCheckBox;
    chkPlaneteMySQLResultat: ThhCheckBox;
    chkPlaneteHTMLResultat: ThhCheckBox;
    chkScanGalaxieAfficheAlliance: ThhCheckBox;
    txtAllies: TEdit;
    cmdRechercheTokenAlliance: TButton;
    chkAfficherQueNomJoueur: ThhCheckBox;
    cmdGalaxyRechercheAlliance: TButton;
    cmdGalaxyRechercheJoueur: TButton;
    txtDBGalaxyJoueur: TEdit;
    lblPlaneteJoueur: TLabel;
    lblPlaneteAlliance: TLabel;
    txtDBGalaxyAlliances: TEdit;
    lblPlanteAllies: TLabel;
    txtDBPlanetes: TMemo;
    TabSheet10: TTabSheet;
    PageControl3: TPageControl;
    TabSheet30: TTabSheet;
    lblFastEvaStatus: TLabel;
    Label195: TLabel;
    Label196: TLabel;
    Memo3: TMemo;
    cmdCheckForFastEvacuation: TButton;
    seFastEvacuationNbVaisseaux: TSpinEdit;
    GroupBox22: TGroupBox;
    Label179: TLabel;
    seFastEvaPosition: TSpinEdit;
    seFastEvaSystem: TSpinEdit;
    seFastEvaGalaxy: TSpinEdit;
    chkFastEvacuationToMoon: ThhCheckBox;
    chkFastEvacuationToPlanete: ThhCheckBox;
    chkFastEvacuationToDebris: ThhCheckBox;
    optFastEvaOrdreStationner: TRadioButton;
    optFastEvaOrdreTransporter: TRadioButton;
    optFastEvaOrdreExploiter: TRadioButton;
    optFastEvaOrdreAttaquer: TRadioButton;
    TabSheet31: TTabSheet;
    Label191: TLabel;
    Label192: TLabel;
    lblTransportMassifEtat: TLabel;
    cmdEffectuerTransportMassif: TButton;
    cbMassiveTransportDest: TComboBox;
    lstcMassiveTransportPlanetes: TCheckListBox;
    GroupBox32: TGroupBox;
    Label198: TLabel;
    Label197: TLabel;
    Label200: TLabel;
    Label199: TLabel;
    Label201: TLabel;
    lblTransportMassifInfos: TLabel;
    seTransportMassifHumanIntervalleMin: TSpinEdit;
    seTransportMassifHumanComplHuman: TSpinEdit;
    GroupBox33: TGroupBox;
    chkMTUseGT: ThhCheckBox;
    chkMTUsePT: ThhCheckBox;
    chkMTUsePTPreference: ThhCheckBox;
    chkMTMemeSiFretTropFaible: ThhCheckBox;
    GroupBox34: TGroupBox;
    Label194: TLabel;
    Label193: TLabel;
    cbTransportMassifSpeed: TComboBox;
    optTransportMassifOrdreTransport: TRadioButton;
    optTransportMassifOrdreStationner: TRadioButton;
    sgChampDeRuines: TAdvStringGrid;
    GroupBox36: TGroupBox;
    optDeplMethodMCD: TRadioButton;
    optDeplMethodCDM: TRadioButton;
    optDeplMethodCMD: TRadioButton;
    optDeplMethodDCM: TRadioButton;
    TabSheet9: TTabSheet;
    Memo4: TMemo;
    lblLAInfos: TLabel;
    cmdAnnulerTransportMassif: TButton;
    popListeAttaque: TBcBarPopupMenu;
    menLAMonter: TMenuItem;
    menLADescendre: TMenuItem;
    N28: TMenuItem;
    menLAEnlever: TMenuItem;
    cmdTest0887: TButton;
    chkTunnelInterdireAccesAdmin: ThhCheckBox;
    tabIRC: TTabSheet;
    cmdIRCConnexion: TButton;
    chkNewsDLAuto: TCheckBox;
    cmdClearPlanetMsg: TButton;
    cmdTunnelSwitch: TButton;
    optDeplMethodMDC: TRadioButton;
    optDeplMethodDMC: TRadioButton;
    chkSondageReorganiseList: ThhCheckBox;
    GroupBox17: TGroupBox;
    seSondageSystemDelay: TSpinEdit;
    seSondageSystemDelayHumain: TSpinEdit;
    chkSondageSystemDelay: ThhCheckBox;
    Label46: TLabel;
    cmdProfilEdit: TButton;
    cmdVerifierConnexion: TButton;
    gbColoration: TGroupBox;
    lblProfilPointsGlobal: TLabel;
    lblProfilPointsFlottes: TLabel;
    Label37: TLabel;
    Label13: TLabel;
    cmdTestSynTime: TButton;
    chkDebogageWebPageSuccess: ThhCheckBox;
    chkLoadAutoGalaxieDB: ThhCheckBox;
    GroupBox11: TGroupBox;
    cmdAlerteAttActiver: TButton;
    cmdAlerteAttDesactiver: TButton;
    cmdAlertAttStopNotifForCurrentAttack: TButton;
    cmdAnalyser: TButton;
    cmdEffacer: TButton;
    txtRapport: TMemo;
    Label15: TLabel;
    cmdInternalState: TButton;
    tabPlaneteDivers: TTabSheet;
    chkDebogageWebPageOnError: ThhCheckBox;
    cmdCdRObserver: TButton;
    menObservationCdR: TMenuItem;
    GroupBox13: TGroupBox;
    txtDirectLoginPageWeb: TEdit;
    Label14: TLabel;
    optDLSpecial: TRadioButton;
    optDLCache: TRadioButton;
    optDLNormal: TRadioButton;
    hintHelp: TJvBalloonHint;
    cmdHelpSpiderAll: TButton;
    cmdHelpSpiderScan: TSpeedButton;
    Label17: TLabel;
    Label25: TLabel;
    cmdHelpRapportPlanete: TSpeedButton;
    cmdClipboardParseRapport: TButton;
    Button3: TButton;
    chkScanFullUnivers: ThhCheckBox;
    chkSondageMsgDebug: ThhCheckBox;
    cbFastEvaSpeed: TComboBox;
    Label27: TLabel;
    TabSheet5: TTabSheet;
    GroupBox18: TGroupBox;
    Label29: TLabel;
    Label30: TLabel;
    Label31: TLabel;
    Label32: TLabel;
    Label34: TLabel;
    chkTunnelCache: TCheckBox;
    menObservationCdRStart: TMenuItem;
    procedure menChangerdeprofil1Click(Sender: TObject);
    procedure sgPlanetesRecentesMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure cmdLAViderClick(Sender: TObject);
    procedure seLANbFreeSlotChange(Sender: TObject);
    procedure cmdListeDAttaqueDebugClick(Sender: TObject);
    procedure sgListeAttaqueDblClickCell(Sender: TObject; ARow, ACol: Integer);
    procedure sgListeAttaqueClickCell(Sender: TObject; ARow, ACol: Integer);
    procedure cmdListeAttaqueUpdateListClick(Sender: TObject);
    procedure cbAttaquePlaneteChange(Sender: TObject);
    procedure chkListeDattenteTraitementActiveClick(Sender: TObject);
    procedure menRecentSuppriFlagTropPeuDevClick(Sender: TObject);
    procedure menAjouterListeDattaqueClick(Sender: TObject);
    procedure cmdTestEvaClick(Sender: TObject);
    procedure menFlotteListRetourClick(Sender: TObject);
    procedure cmdTrackingDebugClick(Sender: TObject);
    procedure memFlotteListEspionnerClick(Sender: TObject);
    procedure sgGridFlotteListClickCell(Sender: TObject; ARow, ACol: Integer);
    procedure chkFastEvacuationToPlaneteClick(Sender: TObject);
    procedure chkFastEvacuationToMoonClick(Sender: TObject);
    procedure chkFastEvacuationToDebrisClick(Sender: TObject);
    procedure cmdCheckForFastEvacuationClick(Sender: TObject);
    procedure menConstructionVoirOptimisationClick(Sender: TObject);
    procedure sgElementsConstructibleClickCell(Sender: TObject; ARow,
      ACol: Integer);
    procedure cmdRessourceCalculerClick(Sender: TObject);
    procedure cmdRessourcesUpdateClick(Sender: TObject);
    procedure switchPlanetMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure sgElementsActionSelectCell(Sender: TObject; ACol, ARow: Integer;
      var CanSelect: Boolean);
    procedure menActionToutEffacerClick(Sender: TObject);
    procedure menActionEnleverClick(Sender: TObject);
    procedure menActionMettreEnBasClick(Sender: TObject);
    procedure menActionMettreEnHautClick(Sender: TObject);
    procedure menActionDescendreClick(Sender: TObject);
    procedure menActionMonterClick(Sender: TObject);
    procedure chkActiveModuleGestionAutoClick(Sender: TObject);
    procedure cmdConstructionMajClick(Sender: TObject);
    procedure switchPlanetClick(Sender: TObject);
    procedure menuMainDrawModuleDrawMenuItem(Sender: TObject;
      AMenuItem: TMenuItem; ACanvas: TCanvas; ARect: TRect;
      State: TOwnerDrawState; ABarVisible: Boolean; var DefaultDraw: Boolean);
    procedure cmdAlertAttStopNotifForCurrentAttackClick(Sender: TObject);
    procedure cmdAlerteAttDesactiverClick(Sender: TObject);
    procedure cmdAlerteAttActiverClick(Sender: TObject);
    procedure sgElementsConstructibleDblClickCell(Sender: TObject; ARow, ACol: Integer);
    procedure menSondageEnleverJoueurClick(Sender: TObject);
    procedure menExporterempire1Click(Sender: TObject);
    procedure menFiltresLuneInclureClick(Sender: TObject);
    procedure menFiltresLuneExclureClick(Sender: TObject);
    procedure menFiltresLuneAfficheOnlyClick(Sender: TObject);
    procedure chkSondageAddOnlyLuneClick(Sender: TObject);
    procedure chkSondageInclureLuneClick(Sender: TObject);
    procedure optExportGalaxyToolClick(Sender: TObject);
    procedure optExportOGSpyClick(Sender: TObject);
    procedure optExportOGSpy302Click(Sender: TObject);
    procedure chkTunnelDesactiveCompressionIEClick(Sender: TObject);
    procedure cmdTunnelGoClick(Sender: TObject);
    procedure txtForumPasswordExit(Sender: TObject);
    procedure txtForumUsernameExit(Sender: TObject);
    procedure txtTunnelRootPassExit(Sender: TObject);
    procedure txtTunnelRootUserExit(Sender: TObject);
    procedure chkTunnelRestreindreLocalClick(Sender: TObject);
    procedure chkTunnelUseRewritingRulesClick(Sender: TObject);
    procedure chkTunnelLancerAuDemClick(Sender: TObject);
    procedure seTunnelPortExit(Sender: TObject);
    procedure timAdditionnalTimer(Sender: TObject);
    procedure wssTunnelClientDisconnect(Sender: TObject; Client: TWSocketClient;
      Error: Word);
    procedure wssTunnelClientCreate(Sender: TObject; Client: TWSocketClient);
    procedure cmdTunnelStopClick(Sender: TObject);
    procedure cmdTunnelLancerClick(Sender: TObject);
    procedure wssTunnelClientConnect(Sender: TObject; Client: TWSocketClient;
      Error: Word);
    procedure tabProfilsEditExit(Sender: TObject);
    procedure menSystemSolaireSpyClick(Sender: TObject);
    procedure timAttackNotificationAndOnTimerTimer(Sender: TObject);
    procedure cmdViewAttackClick(Sender: TObject);
    procedure cmdNewsLaPlusRecenteClick(Sender: TObject);
    procedure cmdNewsSuivanteClick(Sender: TObject);
    procedure cmdNewsPrecedenteClick(Sender: TObject);
    procedure cmdInfosDLNewsClick(Sender: TObject);
    procedure menSystemSolaireAttackClick(Sender: TObject);
    procedure chkDebogageWebPageSuccessClick(Sender: TObject);
    procedure txtOSpyUserIDDblClick(Sender: TObject);
    procedure cmdTestSynTimeClick(Sender: TObject);
    procedure menTrayIconDeleteClick(Sender: TObject);
    procedure menTrayMaximiserClick(Sender: TObject);
    procedure Minimiser1Click(Sender: TObject);
    procedure menFairedisparaitreClick(Sender: TObject);
    procedure timSondeAttackVagueTimer(Sender: TObject);
    procedure cmdSondeAttaqueEffacerDejaSondeClick(Sender: TObject);
    procedure HTMLmodeguerre1Click(Sender: TObject);
    procedure menRecentsCoordsClick(Sender: TObject);
    procedure menFiltreTrierParCoordsClick(Sender: TObject);
    procedure cmdSondeAttackReativeBoutonSondageClick(Sender: TObject);
    procedure cmdSpiderVueGeneraleClick(Sender: TObject);
    procedure cmdClipboardParseRapportClick(Sender: TObject);
    procedure cmdExportStopClick(Sender: TObject);
    procedure cmdExportSQLClick(Sender: TObject);
//    procedure Button5Click(Sender: TObject);
    procedure menSondageEnleverClick(Sender: TObject);
    procedure cmdSondageResetDateClick(Sender: TObject);
    procedure cmdStatsChercheFromUIDClick(Sender: TObject);
    procedure menEspionnerSesPlantesClick(Sender: TObject);
    procedure cmdSondageAllianceClick(Sender: TObject);
    procedure cmdSondageJoueurClick(Sender: TObject);
    procedure menRecentsDefensesClick(Sender: TObject);
    procedure txtAlliance2Enter(Sender: TObject);
    procedure txtAllianceEnter(Sender: TObject);
    procedure cmdScanAlliance2Click(Sender: TObject);
    procedure sgSondagesClickCell(Sender: TObject; ARow, ACol: Integer);
    procedure menRecentAttaqueAutoClick(Sender: TObject);
    procedure cmdAttackWithPTClick(Sender: TObject);
    procedure chkDesactiveColonneDefClick(Sender: TObject);
    procedure cmdSpiderEffacerMsgDebugClick(Sender: TObject);
    procedure cmdFlotteAttaqueRefreshDateClick(Sender: TObject);
    procedure cbAttaqueSpeedRatioChange(Sender: TObject);
    procedure Arrteroperationencours1Click(Sender: TObject);
    procedure rierparrecycleurs1Click(Sender: TObject);
    procedure Recycleurs1Click(Sender: TObject);
    procedure Sauvegarder1Click(Sender: TObject);
    procedure timServiceDelayCmdTimer(Sender: TObject);
    procedure sgVaisseauxEditingDone(Sender: TObject);
    procedure menMettreAJourLempireClick(Sender: TObject);
    procedure menFiltreTrierParFlotteClick(Sender: TObject);
    procedure menFiltreTrierParDateAttaqueClick(Sender: TObject);
    procedure menRecentsTrieLastAttaqueClick(Sender: TObject);
    procedure menRecentsTrieFlotteClick(Sender: TObject);
    procedure menRecentsTrieGTClick(Sender: TObject);
    procedure menStatsAllianceClick(Sender: TObject);
    procedure cmdGalaxieRecherchePlaneteVideClick(Sender: TObject);
    procedure timLoadLastDBAutoTimer(Sender: TObject);
    procedure html1Click(Sender: TObject);
    procedure menFiltreTrierParDateClick(Sender: TObject);
    procedure menFiltreTirerParGTClick(Sender: TObject);
    procedure sgFiltrerClickCell(Sender: TObject; ARow, ACol: Integer);
    procedure menFiltreAuMoinsUneCondRemplieClick(Sender: TObject);
    procedure menFiltreToutesConditionsRempliesClick(Sender: TObject);
    procedure menFlagAucunExclClick(Sender: TObject);
    procedure menFlagAucunInclClick(Sender: TObject);
    procedure menFiltreTousElementNonPresentClick(Sender: TObject);
    procedure menFiltreTousElementPresentClick(Sender: TObject);
    procedure gdSystemSolaireClickCell(Sender: TObject; ARow, ACol: Integer);
    procedure chkSondagePointFlottesNonClasseClick(Sender: TObject);
    procedure chkSondagePointGlobalNonClasseClick(Sender: TObject);
    procedure seSondageStatsLimitFlottesChange(Sender: TObject);
    procedure seSondageStatsLimitGlobalesChange(Sender: TObject);
    procedure cmdViewAppercuListMsgClick(Sender: TObject);
    procedure cmdSondagePointsClick(Sender: TObject);
    procedure menEspionnerClick(Sender: TObject);
    procedure seAttaquePositionChange(Sender: TObject);
    procedure seAttaqueSystemChange(Sender: TObject);
    procedure seAttaqueGalaxieChange(Sender: TObject);
    procedure sgVaisseauxDblClickCell(Sender: TObject; ARow, ACol: Integer);
    procedure cmdChangePlaneteAndUpdateVaisseauxListClick(Sender: TObject);
    procedure seSondageIgnoreDelayLastSondageChange(Sender: TObject);
    procedure menVoirSystmeSolaireClick(Sender: TObject);
    procedure seSondageSystemEndChange(Sender: TObject);
    procedure seSondageSystemStartChange(Sender: TObject);
    procedure cmdMessageListGetClick(Sender: TObject);
    procedure menAttaquerClick(Sender: TObject);
    procedure cmdAttaqueDoItClick(Sender: TObject);
    procedure sgPlanetesPoulesDorDblClickCell(Sender: TObject; ARow,
      ACol: Integer);
    procedure sgPlanetesRecentesDblClickCell(Sender: TObject; ARow,
      ACol: Integer);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure sgPlanetesDblClickCell(Sender: TObject; ARow, ACol: Integer);
    procedure sgVaisseauxCanEditCell(Sender: TObject; ARow, ACol: Integer;
      var CanEdit: Boolean);
    procedure sgVaisseauxGetEditorType(Sender: TObject; ACol, ARow: Integer;
      var AEditor: TEditorType);
    procedure cmdSondageUpdateDateOnlyClick(Sender: TObject);
    procedure cmdSondageUpdateSGridClick(Sender: TObject);
    procedure timSondageTimer(Sender: TObject);
    procedure seSondageDureePourEtrePrisEnCompteChange(Sender: TObject);
    procedure seSpiderGalaxieDureeRecentChange(Sender: TObject);
    procedure menGalaxieChangeDelayClick(Sender: TObject);
    procedure cmdSondageStopClick(Sender: TObject);
    procedure cmdSondageStartClick(Sender: TObject);
    procedure cmdSondageClearNonSondeClick(Sender: TObject);
    procedure cmdSondageClearAllClick(Sender: TObject);
    procedure cbSondagePlaneteChange(Sender: TObject);
    procedure cbGalaxieScanPlaneteChange(Sender: TObject);
    procedure cmdSondageInactifsClick(Sender: TObject);
    procedure cmdSpiderGalaxieScanClick(Sender: TObject);
    procedure menGalaxieSetRangeScanClick(Sender: TObject);
    procedure cmdSpiderStatsScanClick(Sender: TObject);
    procedure cmdSpiderStatsStopClick(Sender: TObject);
    procedure cmdSpiderGalaxieStopClick(Sender: TObject);
    procedure menSpiderLoginClick(Sender: TObject);
    procedure seSystemSolairChoixChange(Sender: TObject);
    procedure Quitter1Click(Sender: TObject);
    procedure menDureeRecent2jClick(Sender: TObject);
    procedure menDureeRecent1jClick(Sender: TObject);
    procedure menDureeRecent10hClick(Sender: TObject);
    procedure menDureeRecent5hClick(Sender: TObject);
    procedure menDureeRecent3hClick(Sender: TObject);
    procedure menDureeRecent2hClick(Sender: TObject);
    procedure menDureeRecent1hClick(Sender: TObject);
    procedure menCaptureRapportDesactiverClick(Sender: TObject);
    procedure menCaptureRapportActiverClick(Sender: TObject);
    procedure cmdRechercheTokenAllianceClick(Sender: TObject);
    procedure cmdVoirPlaneteInexistanteClick(Sender: TObject);
    procedure cmdGalaxyRechercheAllianceClick(Sender: TObject);
    procedure cmdGalaxyRechercheJoueurClick(Sender: TObject);
    procedure sgPlanetesPoulesDorClickCell(Sender: TObject; ARow,
      ACol: Integer);
    procedure chkLoadAutoGalaxieDBClick(Sender: TObject);
    procedure seDBGalaxieChange(Sender: TObject);
    procedure scanDirFichier(Sender: TObject; Nom: string);
    procedure cmdStatsReloadClick(Sender: TObject);
    procedure cmdLoadDBFromProfilsClick(Sender: TObject);
    procedure cmdScanAllianceClick(Sender: TObject);
    procedure cmdAppliqueAnciennetesClick(Sender: TObject);
    procedure N4jours1Click(Sender: TObject);
    procedure N2jours1Click(Sender: TObject);
    procedure N1jour1Click(Sender: TObject);
    procedure N12heures1Click(Sender: TObject);
    procedure N8heures1Click(Sender: TObject);
    procedure N5heures1Click(Sender: TObject);
    procedure N3heure1Click(Sender: TObject);
    procedure N2heure1Click(Sender: TObject);
    procedure N1heure1Click(Sender: TObject);
    procedure cmdBDDUpgradeV2toV3Click(Sender: TObject);
    procedure sgPlanetesRecentesClickCell(Sender: TObject; ARow, ACol: Integer);
    procedure cmdTestClick(Sender: TObject);
    procedure seCurrPlayerPointsChange(Sender: TObject);
    procedure cmdStatsLoadClick(Sender: TObject);
    procedure Copier1Click(Sender: TObject);
    procedure timMonitorClipboardTimer(Sender: TObject);
    procedure cmdClipboardSwitchClick(Sender: TObject);
    procedure cmdAddAttackNowClick(Sender: TObject);
    procedure cmdCreateDBUseItClick(Sender: TObject);
    procedure cmdUpdatePlaneteClick(Sender: TObject);
    procedure sgPlanetesClickCell(Sender: TObject; ARow, ACol: Integer);
    procedure cmdDbLoadClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure cmdEffacerClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure cmdAnalyserClick(Sender: TObject);
    procedure menFlagXXXInclClick(Sender: TObject);
    procedure menFlagYYYExclClick(Sender: TObject);
    procedure menFlagZZZIgnoreClick(Sender: TObject);

    procedure menFlagGalaxieXXXInclClick(Sender: TObject);
    procedure menFlagGalaxieYYYExclClick(Sender: TObject);
    procedure menFlagGalaxieZZZIgnoreClick(Sender: TObject);
    procedure TaskbarEvent(var Msg: TMessage); message WM_TASKABAREVENT;
    procedure WMTunnelOperationCode(var Msg: TMessage); message WM_OPERATION_CODE;
    procedure cmdLAAjouterRecentClick(Sender: TObject);
    procedure cmdEffectuerTransportMassifClick(Sender: TObject);
    procedure seTransportMassifHumanIntervalleMinChange(Sender: TObject);
    procedure cmdVerifierConnexionClick(Sender: TObject);
    procedure sgChampDeRuinesClickCell(Sender: TObject; ARow, ACol: Integer);
    procedure cmdAnnulerTransportMassifClick(Sender: TObject);
    procedure menLAEnleverClick(Sender: TObject);
    procedure menLADescendreClick(Sender: TObject);
    procedure menLAMonterClick(Sender: TObject);
    procedure cmdTest0887Click(Sender: TObject);
    procedure chkNewsDLAutoClick(Sender: TObject);
    procedure cmdClearPlanetMsgClick(Sender: TObject);
    procedure cmdTunnelSwitchClick(Sender: TObject);
    procedure cmdProfilEditClick(Sender: TObject);
    procedure cmdAlerteAttDebugClick(Sender: TObject);
    procedure cmdInternalStateClick(Sender: TObject);
    procedure cmdCdRObserverClick(Sender: TObject);
    procedure cmdHelpSpiderAllClick(Sender: TObject);
    procedure cmdHelpSpiderScanClick(Sender: TObject);
    procedure cmdHelpRapportPlaneteClick(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure menSondageEnleverAllianceClick(Sender: TObject);
    procedure menObservationCdRStartClick(Sender: TObject);
  private
    { Private declarations }
    FExisteTrayIcon : boolean;

    // Fichier de sauvegarde des messages du status
    FFileStatusLog      : TextFile;
    FFileStatusLogEnable: boolean;

    
    // Options globales à tous les profils (options du programme)
    FLocalSetting: TLocalSetting;

    // Base de données des news
    FNewsData: TNewsCollection;

    // Base de données des unités, global à tous les profils et langage
    FUnitesInformations: TCollectionUnitInfos;

    // Base de données des GID, propre à chaque langue
    FGidToStr : TCollectionGIDtoSTR;



    
    FTunnelProfilList: TStringList;

    FRemplaceStrForPageWeb: TSimpleRemplaceStr;

    FForumRelay: TForumDataConn;

    FTunnelSessionId: TCollectionTunnelSessionId;


    FFormCdRMonitorList: TList;


    FCurrDate : int64;

    FExportSQLStop : boolean;
    FDynTimer: TTimer;

    // Si positif, le prog a expire, si nul, on ferme le programme
    bDoExpiration: integer;

    // verification basique
    bExpSimple: boolean;


    // SI différent de nil, les messages de status seront envoyés au socket
    FStatusSocket: TBotServicesClient;

{$IFDEF AUTH_FILE_USE}
    FAuthCaption : string;
    FAuthAProposDone: boolean;
{$ENDIF}


    // Joueur actuel avec la planète sélectionnée
    FCurrentPlayer: TPlayerFinal;
    FCurrPlayerCurrPlanete : TPlaneteInfo;
    FCurrPlayerCurrPlanetForConstruction: TPlaneteInfo;

    FLastLigneSelectedInConstruction: integer;


    // Base de données de rapport
    FBase2DonneesRapports : TCollectionRapportHead;
    FBaseRecent           : TCollectionRapportRecent;
    FBaseVacheAlaid       : TCollectionRapportRecent;
    FBaseCurrSystemSolaire: TCollectionRapportRecent;
    FBaseFiltree          : TCollectionRapportRecent;

    // Base de données de galaxie (cartographie)
    FBase2DonneesPlanete: TCollectionGalaxiePlanete;
    FCurrSystemSolaire  : TListGalaxiePlaneteSP;

    // Copie de pointeurs de la base de données de galaxie
    FChampDeRuineList   : TCollectionGalaxyTriee;


    FNoMessageBoxErrorForRapportEspLecture: boolean;

    

    // definit si une base de données a été chargée
    FInfosBaseDeDonneCharge : boolean;


    // Protective Critical Section object
    ReadWriteCS: TRTLCriticalSection;


    //FRapportTrieLorsDeLajout: boolean;

    FCurrentRapport      : PRapportHead;
    FCurrentSondageSel   : PPlaneteASonder;
    FCurrentSystemSolaire: PGalaxiePlanete;
    FCurrentSocketTunnelRapport: PRapportHead;
    FCurrentIndiceListAttackSel: integer;



    FRapportLastAdd: PRapportHead;

    FRowCurrentRapport: integer;

    FServiceDelayCmd: integer;


    FDossierApp: string;
    FDossierDB: string;
    
    FDossierHtml: string;
    FDossierTunnel: string;

    FDossierGalaxieDB: string;
    FLastClipboard: string;
    FFileBackupRapport: string;
    FFileBackupMsgList: string;
    FFileBackupMsgFlotte: string;

    FDossierStats: string;
    //FDossierLang: string;

    FSondageAlliance: string;

    (*
    FStatsPlayer         : TCollectionPlayerStats;
    FStatsPlayerFlottes  : TCollectionPlayerStats;
    FStatsPlayerRecherche: TCollectionPlayerStats;
    *)

    FStatsGetFileRecent: TScanStatsRecent;
    FStatsAlliance: TCollectionPlayerStatsAllX;


   // FCurrentProfil: TProfilsAttack;

    FScanGalaxie: integer;
    FScanUnivers: integer;
    FScanFileFound: string;
    FScanDB: TCollectionRapportHead;


    FTokenColorization: TStringList;

    // Definit la maniere de quitter le programme, sert pour la protection et eviter
    // de poser la question lors de la fermeture du programme
    FQuitDirect : boolean;


    

    // Sondage
    FSondageDernierEnvoiPrevuPour: int64;
    //FSondagePlanetesList: TCollectionPlaneteASonder;
    //FSondesAttaqueList : TCollectionAttSondeCible;
    FSondageDernierSystemeSolaireSonde: integer;
    FSondageNbEnvoiEffectue: integer;

    FInTimerSondage: boolean;
    FSondageDejaPrevuFin: integer;
    FSondageAttaqueSondeMin: integer; // minimum de sonde pour lancer une attaque




    FCurrVaisseuxList: TCollectionVaisseauSelInfos;
    FCurrVaisseauxItem: PVaisseauSelInfos;
    FNbGTForCurrentRapport: integer;                  // Permet de définir le nombre de GT à mettre
    FNbPTForCurrentRapport: integer;                  // ------------------------------ PT --------


    FForumCookies : TCollectionCookieInfos;


    FCurrentSound : TSoundInfos;

    FDoForumGetAccessInThis     : boolean;
    FForumGetAccessDeniedForHash: int64;
    FForumGetAccessNbEchec      : integer;
    FForumGetDelayedAccessDone  : boolean;


    FLastLigneSelectPlaneteScript : integer;
    FLastIndexSelectFlotteList    : integer;

    FLastShiftStateClickInList        : TShiftState;


    {$IFDEF AUTH_FILE_USE}
        FLicenceKeyMemory: TMemoryStream;
    {$ENDIF}

    procedure TraitementFichierUpdate(updateFile: TFichierUpdateParsing);


    procedure GalaxieNumeroColorationFromCurrPlanete;

    procedure LoadCurrentInForm;
    procedure memRapportOnClick(Sender: TObject);
    procedure InitForm;
    procedure SondageLockCmd(Valeur: boolean);
    procedure cmdSondageJoueurOrAlliance(Str: string; bIsPlayer: boolean);

    function SondageGetPointsVerification(Joueur: string): boolean;
    //function GetNbSondeToSend(TotalRessource: integer; MaxSondeDispo: integer; NiemeAttaque: integer; DureeRapport: int64): integer;




    procedure UpdateDataVaisseaux(Row: integer; Data: PVaisseauSelInfos; Grille: TAdvStringGrid);
    procedure UpdateDataActionScript(Row: integer; Data: PElementActionItem; Grille: TAdvStringGrid);


    procedure UpdateAll;
    procedure UpdateAllSpec(Grille: TAdvStringGrid; BDD: TList);
    
    procedure UpdateStatsAlliance(Grille: TAdvStringGrid);
    procedure UpdateSystemSolaire(Grille: TAdvStringGrid);
    procedure LoadAndUpdateSystemSolaire(System: integer);
    procedure UpdateSondages(Grille: TAdvStringGrid);

    procedure UpdateVaisseaux(Grille: TAdvStringGrid);

    
    procedure RefreshDbList;
    function AnalyseRapport(sRapport: string; bMakeUpdateListRecent, bMakeUpdateListAll, FRapportTrieLorsDeLajout: boolean): integer;
    function AnalyseRapportCurr: integer;

    procedure InitGrille(Grille: TAdvStringGrid);

    procedure LoadStatsFileForUnivers(Uni: integer; bDejaPathConnu: boolean = false);
    procedure RefreshOwnPoints;

    procedure RefreshProfilList;

    procedure LoadProfilInForm;
    procedure LoadProfilInFormLimitation;

    function GetStatsUniPath: string;

    function GetFileFromScanForThisGalaxie(Univers, Galaxie: integer; BDDType: TFichierBDDType): string;
    //function GetFileForThisGalaxie(Galaxie: integer): string;

    procedure SetFileLabelFromGalaxie(Galaxie: integer);
    function RefreshRapportLignes(peRapport: PRapportHead): integer;

    function LoadBaseDeDonnees(FichierFull: string): integer;
    procedure LoadProfilFullPath(FichierFull: string);
    procedure LoadCorrectGidToStrFile;

    procedure OnObjectEnter(Sender: TObject);
    procedure tOnTimerDyn(Sender: TObject);
    procedure tOnTimerDynClose(Sender: TObject);

    procedure CreateBaseDeDonneesFile(Fichier: string);
    function GetRelativeDBPath(Fichier: string): string;

    function ColorizeLigne(Ligne: string): string;

    procedure AfficheMsgGalaxy(const Msg: string);
    procedure AfficheGalaxyPlaneteInfos(pe: PGalaxiePlanete);
    procedure AfficheGalaxyPlaneteFlagsOnlyInfos(pe: PGalaxiePlanete);

    function GetPlaneteTokenForThisPlayer(Joueur: string; sSeparateur: string): string;

    procedure CaptureClipboardActivation;
    procedure CaptureClipboardDesactivation;

    procedure LoadPlaneteInComboAndMenuFromProfils;

    procedure SondageCurrentSelPlaneteInGridList;

    function TraitementMsgList(MsgList: TCollectionOGMessage): integer;

    function SondageCheckAndTryToAddThisCoord(Coord: TPlanetLocation; peGalaxie: PGalaxiePlanete; OverrideRapportFlags: boolean): boolean;
    function AppTerminating: boolean;


    procedure UpdateSpeedAndDeutUsed;

    procedure ModifStatsMenu(Coord: TPlanetLocation);
    

    // Attaque fonction
    procedure ReadVaisseauxQuantite;
    procedure AttaqueLoadStatsCible;

    // Spider fonctions
    function SpiderDoLogin: integer;
    function SpiderGalaxieGetSelectedPlanete: TPlanetLocation;
    procedure SpiderGalaxieSetRange(Planete: TPlanetLocation; Distance: integer);
    procedure SpiderGalaxieSetRangeFromCurrent(Distance: integer);
    procedure SpiderGalaxieSetToScan(Galaxie: integer);

    function SpiderChangePlaneteToThis(Planete: TPlanetLocation): integer;
    function SpiderChangePlaneteToGalaxieScanSelected: integer;


    // Serveur web fonctions
    //procedure Services_Commande02_Profils_GetList(Socket: TBotServicesClient);
    //procedure Services_Commande03_Profil_Chargement(Socket: TBotServicesClient; IndexProfil: string);
    //procedure Services_Commande04_Profil_Voir(Socket: TBotServicesClient);
    procedure Services_Commande05_DB_Chargement(Socket: TBotServicesClient; IdGalaxie: string);
    procedure Services_Commande06_Recents_Voir(Socket: TBotServicesClient);
    procedure Services_Commande_EnvoiRowToSocket(Data: TRapportHead; Socket: TBotServicesClient);
    procedure Services_Commande07_RecentChangeDuree(Socket: TBotServicesClient; sDuree: string);

    procedure Services_Commande10_SpiderVoir(Socket: TBotServicesClient);
    procedure Services_Commande11_SpiderScan(Socket: TBotServicesClient; Params: string);
    procedure Services_Commande12_SpiderSondage(Socket: TBotServicesClient; Params: string);
    procedure Services_Commande13_SpiderStatsRefresh(Socket: TBotServicesClient);
    procedure Services_Commande14_SpiderLogin(Socket: TBotServicesClient);
    procedure Services_Commande15_SpiderLireMsg(Socket: TBotServicesClient);

    procedure Services_Commande20_VoirMsgStatus(Socket: TBotServicesClient);
    procedure Services_Commande21_Sondage_VoirList(Socket: TBotServicesClient);


    procedure AfficheRE(pGalaxy: PGalaxiePlanete);

    //procedure RefreshLangCombo;
    procedure SetWebPagesSaving;
    procedure CleanupEverything;
    procedure ProxyUpdateLabel;

    procedure News_PlaceOnLastest;
    procedure News_AfficheCurr;
    procedure News_RefreshNonLuesLabel;


    function SoundLoad: boolean;

    function SoundPlay(Fichier: string): boolean;
    procedure SoundFreeCurrent;

    procedure LoadLanguageFileListForMenu;
    procedure LanguageFileChangeOnClick(Sender: TObject);


    procedure LoadPlanetInForm(Planete: TPlaneteInfo);

    procedure AfficheResRowInGrid(Grille: TAdvStringGrid; Res: TList; cRes: TOGRessourceAll; DoClear: boolean);

    procedure AfficheActionInGrid(Grille: TAdvStringGrid; Action: TCollectionElementActionItem);

    procedure RefreshPlanetGridAutoConstruction(Joueur: TPlayerGestion);

    procedure StopTimers;
    procedure AfficheResultatOptimization(r: TResultatBestProd);


    procedure UpdateDataSondageForSocket(Data: TPlaneteASonder; t: TTemplatePage);
    procedure UpdateSondagesForSocket(t: TTemplatePage);


    procedure UpdateAllSpecForSocket(t: TTemplatePage; BDD: TList);
    procedure UpdateDataForSocket(Data: TRapportHead; t: TTemplatePage);

    procedure SaveProfilIfIsValid;

  public
    { Public declarations }
    procedure Lock;
    procedure Unlock;


    procedure Status(const Msg: string);
    procedure StatusNews(const Msg: string);
    procedure StatusAlerteAtt(const Msg: string);

    procedure StatusSockets(const Msg: string);
    procedure CreateFile(Fichier: string; tDate: TSystemTime);

    procedure EnableOrDisableWebActionButton(bValeur: boolean);
    procedure EnableOrDisableBDDButton(bValeur: boolean);

    procedure RefreshMenuFiltreCheckbox;
    procedure UpdateFiltreeItem;
    procedure FiltreAddPlanete(pe: PRapportHead);

    procedure RefreshPlanetGrid(Joueur: TPlayerGestion; DontAfficheStatus: boolean = false);
    procedure AfficheTOGRessourceAll(Element: TOGRessourceAll);
    procedure AfficheTOGRessourceAllProd(Element: TOGRessourceAll);
    
    procedure TrayIconCreate(const Titre: string);
    procedure TrayIconChangeTitle(const NouveauTitre: string);
    procedure TrayIconDestroy;

    procedure DoOnRequest(Sender: TObject);
    procedure TunnelSendFile(s: TTunnelHttpConnection; RelativePath: string);

    procedure TunnelTraitement_RELAY(s: TTunnelHttpConnection; Params: string);
    procedure TunnelTraitement_GAME(s: TTunnelHttpConnection; Params: string);
    procedure TunnelTraitement_FORUM(s: TTunnelHttpConnection; Params: string);

    procedure TunnelTraitement_ROBOT(s: TTunnelHttpConnection; Params: string);
    procedure TunnelTraitement_ROBOT_Operation(s: TTunnelHttpConnection; t: TTemplatePage);
    procedure TunnelROBOT_TemplateSetGlobalValue(s: TTunnelHttpConnection; t: TTemplatePage);
    procedure TunnelROBOT_TemplateSetPlaneteList(s: TTunnelHttpConnection; t: TTemplatePage);

    function TunnelGetMoreDataForTunnel_Apercu(sPageWeb: string): string;

    function TunnelROBOT_SetSondageData(s: TTunnelHttpConnection): integer;
    function TunnelROBOT_SetSondageData_ParPoints(s: TTunnelHttpConnection): integer;

    function TunnelGetFullFile(RelativePath: string): string;


    function GetForumCanAccess: boolean;
    procedure ConfigForumSocket(var Socket: THttpCli);
    function DoForumGetAccess: TBoardFonctionLoginResult;

    procedure OnAttackNouvelle(Infos: PAlarmeAttack);
    procedure OnAttackAnnule(Infos: PAlarmeAttack);
    procedure AlerteAttaqueDebug;
    procedure FlotteTrackingDebug;
    procedure ListeDAttaqueDebug;

    procedure playerOnItemsCostChange(Joueur: TPlayerGestion; Planete: TPlaneteInfo);

    procedure OpenCdRMonitor;

    procedure ShowHintHelp(Where: TControl; Duration: integer = -1; DoSleepPause: boolean = true);







    //
    // Client IRC
    //


  end;

  function DateHeureCreationFichier2(fichier: string): TDateTime;
  function DateHeureCreationFichier1(fichier: string): TDateTime;




var
  frmRapportHistorique: TfrmRapportHistorique;



implementation

uses uConfirmation, uStatsPlayer, frmConfigSound, modInitGrille,
  frmVaisseauxEdit, frmProfilChoix, frmIRC, frmFLX, uProfilConfig,
  frmOGSpyExport;

{$R *.dfm}

const
  LongDayNames: array[1..7] of string = ('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi');
  LongMonthNames: array[1..12] of string = ('Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet',
                                            'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre');

procedure DoSleep(const Duree: integer);
var i, max: integer;
begin

    max := GetTickCount + Duree;

    repeat
       Application.ProcessMessages;
       Sleep(2);

    until GetTickCount > max;


end;


procedure ShowBalloonTip(hWnd: THandle;
                         Icon: integer;
                         Title: pchar;
                         Text: PWideChar;
                         BackCL, TextCL: TColor;
                         dwDuration: DWORD;
                         Itime: longint = 0);
const
   TOOLTIPS_CLASS = 'tooltips_class32';
   TTS_ALWAYSTIP = $01;
   TTS_NOPREFIX = $02;
   TTS_BALLOON = $40;
   TTF_SUBCLASS = $0010;
   TTF_TRANSPARENT = $0100;
   TTF_CENTERTIP = $0002;
   TTM_ADDTOOL = $0400 + 50;
   TTM_SETTITLE = (WM_USER + 32);
   ICC_WIN95_CLASSES = $000000FF;

type
   TOOLINFO = packed record
      cbSize: Integer;
      uFlags: Integer;
      hwnd: THandle;
      uId: Integer;
      rect: TRect;
      hinst: THandle;
      lpszText: PWideChar;
      lParam: Integer;
   end;

var
   hWndTip: THandle;
   ti: TOOLINFO;
begin
   hWndTip := CreateWindow(TOOLTIPS_CLASS, nil,
   WS_POPUP or TTS_NOPREFIX or TTS_BALLOON or TTS_ALWAYSTIP,
   0, 0, 0, 0, hWnd, 0, HInstance, nil);

   if hWndTip <> 0 then begin
      SetWindowPos(hWndTip, HWND_TOPMOST, 0, 0, 0, 0,
      SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
      ti.cbSize := SizeOf(ti);
      ti.uFlags := TTF_CENTERTIP or TTF_TRANSPARENT or TTF_SUBCLASS;
      ti.hwnd := hWnd;
      ti.lpszText := Text;
      Windows.GetClientRect(hWnd, ti.rect);

      SendMessage(hWndTip, TTM_SETTIPBKCOLOR, BackCL, 0);
      SendMessage(hWndTip, TTM_SETTIPTEXTCOLOR, TextCL, 0);
      SendMessage(hWndTip, TTM_ADDTOOL, 1, Integer(@ti));
      SendMessage(hWndTip, TTM_SETTITLE, Icon mod 4, Integer(Title));
      SendMessage(hWndTip, TTM_SETDELAYTIME,dwDuration,Itime);
   end;

end;


function GetCurrDate(tDate: TDateTime): string;
var JourNum, iMois: integer;
    sJourNum: string;

    DayOfWeekNum: integer;
begin
     Result := '';

     // Le numero de jour
     JourNum := DayOf(tDate);
     sJourNum := IntToStr(JourNum);
     if length(sJourNum) = 1 then
        sJourNum := '0' + sJourNum;


     // Le jour de la semaine commence à dimanche
     DayOfWeekNum := DayOfWeek(tDate);
     iMois        := MonthOf(tDate);

     if (DayOfWeekNum < 1) or (DayOfWeekNum > 7) then begin
        exit;
     end;
     if (iMois < 1) or (iMois > 12) then begin
        exit;
     end;

     Result := format('%s %s %s %d', [LongDayNames[DayOfWeekNum], sJourNum, LongMonthNames[iMois], YearOf(tDate)]);


end;

procedure DoSleep5(dwDuree: longword);
begin

   while dwDuree > 5 do begin
      Dec(dwDuree, 5);
      Sleep(5);
      Application.ProcessMessages;
   end;

end;


procedure TfrmRapportHistorique.StopTimers;
var i: integer;
begin
   timMonitorClipboard.Interval := 0;
   timSondage.Interval := 0;
   timServiceDelayCmd.Interval := 0;
   timSondeAttackVague.Interval := 0;
   timLoadLastDBAuto.Interval := 0;
   timAdditionnal.Interval := 0;
   timAttackNotificationAndOnTimer.Interval := 0;
   timAttackNotificationAndOnTimer.Enabled  := false;

   //Hide;
   //DoSleep5(30);
end;


procedure TfrmRapportHistorique.WMTunnelOperationCode(var Msg: TMessage);
begin
   case Msg.WParam of
       TUNNEL_OPCODE_SPIDER_DO_LOGIN: begin
                if menSpiderLogin.Enabled then begin
                   menSpiderLoginClick(menSpiderLogin);
                end;
             end;

       TUNNEL_OPCODE_STATS_RECOLTE: begin
                if cmdSpiderStatsScan.Enabled then begin
                   cmdSpiderStatsScanClick(cmdSpiderStatsScan);
                end;
             end;

       TUNNEL_OPCODE_LIRE_MSG: begin
                if cmdMessageListGet.Enabled then begin
                   cmdMessageListGetClick(cmdMessageListGet);
                end;
             end;

       TUNNEL_OPCODE_SPIDER_SCAN: begin
                if cmdSpiderGalaxieScan.Enabled then begin
                   cmdSpiderGalaxieScanClick(cmdSpiderGalaxieScan);
                end;
             end;

   end;


end;


procedure TfrmRapportHistorique.Lock;
begin
    EnterCriticalSection(ReadWriteCS);
end;

procedure TfrmRapportHistorique.Unlock;
begin
    LeaveCriticalSection(ReadWriteCS);
end;


procedure TfrmRapportHistorique.TrayIconChangeTitle(const NouveauTitre: string);
var NotifyIconData: TNotifyIconData;
    i, lng : integer;
begin


   if FExisteTrayIcon then begin
        // Tray icon
        Fillchar(NotifyIconData, Sizeof(NotifyIconData), 0);
        NotifyIconData.cbSize           := Sizeof(NotifyIconData);
        NotifyIconData.Wnd              := Handle;
        NotifyIconData.uFlags           := NIF_MESSAGE or NIF_ICON or NIF_TIP;
        NotifyIconData.uCallbackMessage := WM_TASKABAREVENT;
        NotifyIconData.hIcon            := Application.icon.Handle;

        lng := length(NouveauTitre);
        if lng > 0 then begin
           if lng > 63 then lng := 63;

           for i := 1 to lng do
               NotifyIconData.szTip[i - 1]    := NouveauTitre[i];

           for i := lng to 63 do
               NotifyIconData.szTip[i] := #0;

        end else
           NotifyIconData.szTip            := CNT_TITLE_TRAYICON;

           
        Shell_NotifyIcon(NIM_MODIFY, @NotifyIconData);

   end else begin
       // L'icone n'existe pas, la créée
       TrayIconCreate(NouveauTitre);
   end;

end;

procedure TfrmRapportHistorique.TrayIconCreate(const Titre: string);
var NotifyIconData: TNotifyIconData;
    i, lng : integer;

begin

  if FExisteTrayIcon then begin
     // L'icone existe déjà
     if Titre <> '' then
        TrayIconChangeTitle(Titre);

     exit;
  end;

  // Tray icon
  Fillchar(NotifyIconData, Sizeof(NotifyIconData), 0);
  NotifyIconData.cbSize           := Sizeof(NotifyIconData);
  NotifyIconData.Wnd              := Handle;
  NotifyIconData.uFlags           := NIF_MESSAGE or NIF_ICON or NIF_TIP;
  NotifyIconData.uCallbackMessage := WM_TASKABAREVENT;
  NotifyIconData.hIcon            := Application.icon.Handle;


  lng := length(Titre);
  if lng > 0 then begin
     if lng > 63 then lng := 63;
     for i := 1 to lng do
         NotifyIconData.szTip[i - 1]    := Titre[i];

     for i := lng to 63 do
         NotifyIconData.szTip[i] := #0;

  end else
     NotifyIconData.szTip            := CNT_TITLE_TRAYICON;


  Shell_NotifyIcon(NIM_ADD, @NotifyIconData);

  FExisteTrayIcon := true;
end;


procedure TfrmRapportHistorique.TrayIconDestroy;
var NotifyIconData: TNotifyIconData;
begin

  if NoT(FExisteTrayIcon) then
     // L'icone n'existe déjà pas
     exit;

  // tray icon
  FillChar(NotifyIconData, Sizeof(NotifyIconData), 0);
  NotifyIconData.cbSize := Sizeof(NotifyIconData);
  NotifyIconData.Wnd := Self.Handle;
  NotifyIconData.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
  NotifyIconData.uCallbackMessage := WM_TASKABAREVENT;
  NotifyIconData.hIcon := Application.Icon.Handle;
  NotifyIconData.szTip := CNT_TITLE_TRAYICON;
  Shell_NotifyIcon(NIM_DELETE, @NotifyIconData);

  FExisteTrayIcon := false;
end;

procedure TfrmRapportHistorique.TaskbarEvent(var Msg: TMessage);
var p: tpoint;
begin

  if msg.LParam = WM_RButtonDown then begin
    SetForegroundWindow(Handle);
    GetCursorPos(p);
    PopupTray.Popup(p.x, p.y);
    PostMessage(Handle, WM_NULL, 0, 0);
  end;

  if msg.LParam = WM_LButtonDblClk then begin
     SetForegroundWindow(Handle);
     Application.Restore;

     SendMessage(Handle, WM_NEXTDLGCTL, 0, 0);

     Show;
     SetFocus;

  end;

  {Valeur de msg.LParam:
  WM_MouseMove,WM_LButtonDown,WM_LButtonUp
  WM_LButtonDblClk,WM_RButtonDown,WM_RButtonUp,WM_RButtonDblClk }

end;

procedure TfrmRapportHistorique.SoundFreeCurrent;
begin
    if FCurrentSound.Stream <> nil then begin
       // s'assure que la musique n'est pas en cours de lecture
       if FCurrentSound.Channel <> CNT_SOUND_CHANNEL_NOT_PLAYING then begin
          FSOUND_StopSound(FCurrentSound.Channel);
          FCurrentSound.Channel := CNT_SOUND_CHANNEL_NOT_PLAYING;
       end;

       // ferme le stream
       FSOUND_Stream_Close(FCurrentSound.Stream);

    end;

    FCurrentSound.Fichier := '';
    FCurrentSound.Channel := CNT_SOUND_CHANNEL_NOT_PLAYING;
    FCurrentSound.Stream  := nil;
    FCurrentSound.DurationMilliSecondes  := -1;
    FCurrentSound.DurectionSecondes      := -1;
end;

function TfrmRapportHistorique.SoundPlay(Fichier: string): boolean;
begin

    if NoT(FMOD_Initialized) then begin
       SoundLoad;

       if NoT(FMOD_Initialized) then begin
          // echec d'intialisation
          Result := False;
          exit;
       end;
    end;

    if FCurrentSound.Stream <> nil then begin
       if SameText(Fichier, FCurrentSound.Fichier)  then begin
          // même fichier, on le lit
          Result := true;

          if FCurrentSound.Channel <> CNT_SOUND_CHANNEL_NOT_PLAYING then begin
             if FSOUND_IsPlaying(FCurrentSound.Channel) then begin
                FSOUND_StopSound(FCurrentSound.Channel);
                FSOUND_SetCurrentPosition(FCurrentSound.Channel, 0);
             end;

          end;

          FCurrentSound.Channel := FSOUND_Stream_Play(FSOUND_FREE, FCurrentSound.Stream);
          if FCurrentSound.Channel < 0 then begin
             FCurrentSound.Channel := CNT_SOUND_CHANNEL_NOT_PLAYING;
             Result := false;
          end;

          exit;



       end else begin
          // s'assure que la musique n'est pas en cours de lecture
          if FCurrentSound.Channel <> CNT_SOUND_CHANNEL_NOT_PLAYING then begin
             if FSOUND_IsPlaying(FCurrentSound.Channel) then begin
                FSOUND_StopSound(FCurrentSound.Channel);
             end;
             FCurrentSound.Channel := CNT_SOUND_CHANNEL_NOT_PLAYING;
          end;


          // ferme le stream
          FSOUND_Stream_Close(FCurrentSound.Stream);
       end;
    end;

    FCurrentSound.Fichier := '';
    FCurrentSound.Channel := CNT_SOUND_CHANNEL_NOT_PLAYING;
    FCurrentSound.Stream  := nil;
    FCurrentSound.DurationMilliSecondes  := -1;
    FCurrentSound.DurectionSecondes      := -1;

    Result := false;
    if FileExists(Fichier) = false then exit;

    FCurrentSound.Stream := FSOUND_Stream_Open(PChar(Fichier), FSOUND_2D or FSOUND_STEREO, 0, 0);

    if FCurrentSound.Stream = nil then begin
       // son mal chargé
       // erreur
       exit;
    end;
    FCurrentSound.Fichier := Fichier;

    FCurrentSound.DurationMilliSecondes := FSOUND_Stream_GetLengthMs(FCurrentSound.Stream);
    FCurrentSound.DurectionSecondes     := FCurrentSound.DurationMilliSecondes div 1000;

    FCurrentSound.Channel := FSOUND_Stream_Play(FSOUND_FREE, FCurrentSound.Stream);
    if FCurrentSound.Channel < 0 then begin
       FCurrentSound.Channel := CNT_SOUND_CHANNEL_NOT_PLAYING;
       Result := false;
    end else begin
       Result := true;
    end;


end;


function TfrmRapportHistorique.SoundLoad: boolean;
begin

    Result := msndInit(FLocalSetting.ConfGet(CNT_LOCALSETTING_FMOD_Output), FLocalSetting.ConfGet(CNT_LOCALSETTING_FMOD_Driver));

    if Result then begin
       Status(_('Configuration sonore - Chargement réussi'));
    end else begin
       Status(_('Configuration sonore - Chargement échoué'));
    end;

end;



procedure TfrmRapportHistorique.ListeDAttaqueDebug;
var CurrDate: int64;
    pe: PLAItem;
    peAttack: PLAActionOrdreAttaquer;
    i: integer;
begin

    if FCurrentPlayer.cListeDattaque.Count > 0 then begin
       CurrDate := DateTimeToUnix(Now);

       Status('###########################');

       for i := 0 to FCurrentPlayer.cListeDattaque.Count - 1 do begin
           pe := FCurrentPlayer.cListeDattaque.Items[i];



           Status('Depart: ' + mbtPlanetLocationToStr(pe.Depart) + ' -> Cible: ' + mbtPlanetLocationToStr(pe.Operation.Cible));

           if pe.ActionOrdreType = laatAttaquer then begin
              peAttack := pe.ActionOrdre;
              Status('Ordre attaquer');

              Status('RessourceMin: ' + IntToStr(peAttack.RessourceMin) + ' - DefenseScoreMax: ' + IntToStr(peAttack.DefenseScoreMax) + ' - RecyclageNbRessourceMax: ' + IntToStr(peAttack.RecyclageNbRessourceMax));

              Status('Sondage: ' + mbtPlanetLocationToStr(peAttack.Sondage.Planete));
              Status('-> DureePourAtteindreLaCible: ' + IntToStr(peAttack.Sondage.DureePourAtteindreLaCible) + ' - DoAvantImpact: ' + IntToStr(peAttack.Sondage.DoAvantImpact) + ' - DoAvantAttaque: ' + IntToStr(peAttack.Sondage.DoAvantAttaque));
              Status('-> NbSondes: ' + IntToStr(peAttack.Sondage.NbSondes));
              Status('-> FlotteImpactDate: ' + IntToStr(peAttack.Sondage.FlotteImpactDate) + ' - dans: ' + iif(peAttack.Sondage.FlotteImpactDate - CurrDate >= 0, ESBDGetDureeStrings(peAttack.Sondage.FlotteImpactDate - CurrDate, true), 'déjà arrivée (ou jamais)'));
              Status('-> FlotteLaunchDate: ' + IntToStr(peAttack.Sondage.FlotteLaunchDate) + ' - il y a: ' + iif(CurrDate - peAttack.Sondage.FlotteLaunchDate <= CurrDate, ESBDGetDureeStrings(CurrDate - peAttack.Sondage.FlotteImpactDate, true), 'pas lancé'));
              Status('-> NextRapportChecking: ' + IntToStr(peAttack.Sondage.NextRapportChecking) + ' - dans: ' + iif(peAttack.Sondage.NextRapportChecking - CurrDate >= 0, ESBDGetDureeStrings(peAttack.Sondage.NextRapportChecking - CurrDate, true), 'déjà effectué (ou jamais)'));

           end else begin
              Status('Ordre différent d''attaquer');
              peAttack := nil;
           end;


           Status('###########################');
       end;


    end else begin
        Status('Pas d''élement en attente');
    end;
end;

procedure TfrmRapportHistorique.FlotteTrackingDebug;
begin
    FCurrentPlayer.Lock;
    
    try
       FCurrentPlayer.FlotteTrackingDebug;
    finally
       FCurrentPlayer.Unlock;
    end;

end;

procedure TfrmRapportHistorique.AlerteAttaqueDebug;
begin

    FCurrentPlayer.Lock;
    try
      FCurrentPlayer.AlerteAttDebug(false);
    finally
      FCurrentPlayer.Unlock;
    end;

end;

procedure TfrmRapportHistorique.OnAttackNouvelle(Infos: PAlarmeAttack);
var Duree: integer;
begin
   if Infos = nil then begin
      exit;
   end;

   Duree := Infos.DateImpactLocal - DateTimeToUnix(Now);

   StatusAlerteAtt(format(_('Nouvelle attaque détectée: %s vers %s'), [mbtPlanetLocationToStr(Infos.Depart), mbtPlanetLocationToStr(Infos.Arrivee)]));

   if Duree > 0 then begin
      StatusAlerteAtt(format(_('-> Impact dans: %s'), [ESBDGetDureeStrings(Duree, true)]));

   end else begin
      StatusAlerteAtt(format(_('-> Impact dans: %d'), [Duree]));
   end;

end;

procedure TfrmRapportHistorique.OnAttackAnnule(Infos: PAlarmeAttack);
begin
   if Infos = nil then begin
      exit;
   end;
               

   StatusAlerteAtt(format(_('Attaque annulée: %s vers %s'), [mbtPlanetLocationToStr(Infos.Depart), mbtPlanetLocationToStr(Infos.Arrivee)]));

end;



(*
// Fonction incluse dans TCollectionVaisseauSelInfos directement
function lGetTotalRessource(VaisseuxList: TCollectionVaisseauSelInfos; UnitesInformations: TCollectionUnitInfos): TOGRessourceAll;
var i: integer;
    pe: PVaisseauSelInfos;
    peInfos: PUnitInfos;
begin

    Result.Metal := 0;
    Result.Cristal := 0;
    Result.Deuterium := 0;
    Result.Energie := 0;

    if VaisseuxList.Count = 0 then exit;


    for i := 0 to VaisseuxList.Count - 1 do begin
        pe := VaisseuxList.Items[i];

        peInfos := UnitesInformations.Get_Pointeur(pe.GID);

        if (peInfos <> nil) and (pe.Max > 0) then begin
            Result := AddPrix(Result, peInfos.Prix, pe.Max);
        end;

    end;

end;
*)



procedure TfrmRapportHistorique.AfficheTOGRessourceAllProd(Element: TOGRessourceAll);
var TotalSemaine: integer;
begin
   Status(format(_('    Metal: %s, soit %s par jour et %s par semaine'), [sfcFormatStrToMilliersPX(Element.Metal, 7), sfcFormatStrToMilliersPX(Element.Metal * 24, 9), sfcFormatStrToMilliersPX(Element.Metal * 24 * 7, 10)]));
   Status(format(_('  Cristal: %s, soit %s par jour et %s par semaine'), [sfcFormatStrToMilliersPX(Element.Cristal, 7), sfcFormatStrToMilliersPX(Element.Cristal * 24, 9), sfcFormatStrToMilliersPX(Element.Cristal * 24 * 7, 10)]));
   Status(format(_('Deuterium: %s, soit %s par jour et %s par semaine'), [sfcFormatStrToMilliersPX(Element.Deuterium, 7), sfcFormatStrToMilliersPX(Element.Deuterium * 24, 9), sfcFormatStrToMilliersPX(Element.Deuterium * 24 * 7, 10)]));
   Status(format(_('  Energie: %7d'), [Element.Energie]));

   TotalSemaine := Element.Metal * 24;
   TotalSemaine := TotalSemaine + Element.Cristal * 24;
   TotalSemaine := TotalSemaine + Element.Deuterium * 24;
   Status(format(_('Points par jour: %s'), [sfcFormatStrToMilliersP(TotalSemaine div 1000)]));
   Status(format(_('Points par semaine: %s'), [sfcFormatStrToMilliersP((TotalSemaine * 7) div 1000)]));
end;

procedure TfrmRapportHistorique.AfficheTOGRessourceAll(Element: TOGRessourceAll);
begin
   Status(format(_('    Metal: %s'), [sfcFormatStrToMilliersPX(Element.Metal, 7)]));
   Status(format(_('  Cristal: %s'), [sfcFormatStrToMilliersPX(Element.Cristal, 7)]));
   Status(format(_('Deuterium: %s'), [sfcFormatStrToMilliersPX(Element.Deuterium, 7)]));
   Status(format(_('  Energie: %s'), [sfcFormatStrToMilliersPX(Element.Energie, 7)]));
end;



procedure TfrmRapportHistorique.RefreshPlanetGrid(Joueur: TPlayerGestion; DontAfficheStatus: boolean = false);
var lPlanet: TListPlanet;
    i, c: integer;
    cPlanet: TPlaneteInfo;
begin

    lPlanet := Joueur.allPlanetes;

    if (lPlanet = nil) or (lPlanet.Count = 0) then  begin
       if gsPlanet.ColCount > 2 then
          gsPlanet.RemoveCols(2, gsPlanet.ColCount - 2);

       exit;
    end;

    // Supprime les colonnes super flu
    if gsPlanet.ColCount > lPlanet.Count + 1 then begin
       gsPlanet.RemoveCols(2, gsPlanet.ColCount - 1 - lPlanet.Count);
    end;


    c := 1;
    for i := 0 to lPlanet.Count - 1 do begin

        if gsPlanet.ColCount = c then begin
           gsPlanet.AddColumn;
         //  c := sgActionScriptItemsDispo.ColCount - 1;
        end;

        cPlanet := lPlanet.Items[i];

        msgUpdateEmpirePlanetColonne(gsPlanet, c, cPlanet, FGidToStr);

        Inc(c);
    end;


    
    if DontAfficheStatus = false then begin
       Status(_('Production totale:'));
       AfficheTOGRessourceAllProd(FCurrentPlayer.allPlanetes.ProductionTotale);

       Status(_('Ressources totales last:'));
       AfficheTOGRessourceAll(FCurrentPlayer.allPlanetes.RessourcesTotale);

       Status(_('Ressources totales estimées:'));
       AfficheTOGRessourceAll(FCurrentPlayer.allPlanetes.RessourcesEstimTotale);
    end;

end;


procedure TfrmRapportHistorique.FiltreAddPlanete(pe: PRapportHead);
begin

          if FCurrentPlayer.Conf.FiltreLuneState = CNT_FILTRE_LNE_STATE_EXCLURE then begin
             if mbtIsLune(pe.PlaneteLocation) = false then begin
                FBaseFiltree.Add(pe);
             end;

          end else if FCurrentPlayer.Conf.FiltreLuneState = CNT_FILTRE_LNE_STATE_LUNE_SEULEMENT then begin
             if mbtIsLune(pe.PlaneteLocation) then begin
                FBaseFiltree.Add(pe);
             end;

          end else begin
             FBaseFiltree.Add(pe);
          end;


end;


procedure TfrmRapportHistorique.UpdateFiltreeItem;
var pe: PRapportHead;
    peGalaxie: PGalaxiePlanete;
    i: integer;
begin

    FBaseFiltree.Clear;

    if FBase2DonneesRapports.Count = 0 then exit;


    for i := 0 to FBase2DonneesRapports.Count - 1 do begin
       pe := FBase2DonneesRapports.Items[i];

       if sfcFlagsOneOrMoreAreIn(pe.Flags, FCurrentPlayer.Conf.FiltreFlagsRapportExclu) then begin
          // Contient des flags exclu
          Continue;

       end;

       peGalaxie := FBase2DonneesPlanete.Get_Pointeur(pe.PlaneteLocation);
       if peGalaxie <> nil then begin
          if sfcFlagsOneOrMoreAreIn(peGalaxie.Flags, FCurrentPlayer.Conf.FiltreFlagsGalaxieExclu) then begin
             // Contient des flags exclu
             Continue;

          end;

       end;


       // Tout les autres options sont soit incluses, soit sans importances
       if FCurrentPlayer.Conf.FiltrePresenceTousDefaut then begin
          // On peut les ajouter sans problème
          FiltreAddPlanete(pe);



       end else begin
          // Sinon il faut vérifier les flags d'inclusion

          if FCurrentPlayer.Conf.FiltreFlagsAucunRapportInclu then begin
             // ceux sans flags sont inclu
             if pe.Flags = 0 then begin

                if peGalaxie = nil then begin
                   FiltreAddPlanete(pe);
                   Continue;
                end;

                if peGalaxie.Flags = 0 then begin
                   FiltreAddPlanete(pe);
                   Continue;
                end;
             end;


          end else if (pe.Flags = 0) then begin

                if peGalaxie = nil then begin
                   Continue;
                end;

                if peGalaxie.Flags = 0 then begin
                   Continue;
                end;
          end;



          if FCurrentPlayer.Conf.FiltreInclusionMethodAllVerif then begin

             if (FCurrentPlayer.Conf.FiltreFlagsRapportInclu > 0) and NoT(sfcFlagsIsIn(pe.Flags, FCurrentPlayer.Conf.FiltreFlagsRapportInclu))  then begin
                // Ne contient pas tout les flags requis
                Continue;

             end;


             if peGalaxie <> nil then begin
                if (FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu > 0) and NoT(sfcFlagsOneOrMoreAreIn(peGalaxie.Flags, FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu)) then begin
                   // Ne contient pas tous les flags requis
                   Continue;

                end;

             end;

          end else begin
             if (FCurrentPlayer.Conf.FiltreFlagsRapportInclu > 0) and NoT(sfcFlagsOneOrMoreAreIn(pe.Flags, FCurrentPlayer.Conf.FiltreFlagsRapportInclu)) then begin
                // Ne contient pas tous les flags requis
                Continue;

             end;

             if peGalaxie <> nil then begin
                if (FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu > 0) and NoT(sfcFlagsOneOrMoreAreIn(peGalaxie.Flags, FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu)) then begin
                   // Ne contient pas tous les flags requis
                   Continue;

                end;

             end;

          end;

          FiltreAddPlanete(pe);

       end;

    end;

end;


procedure TfrmRapportHistorique.RefreshMenuFiltreCheckbox;
begin

   menFlagTropBienDefIncl.Checked := sfcFlagsIsIn(FLAG_TROP_BIEN_DEF, FCurrentPlayer.Conf.FiltreFlagsRapportInclu);
   menFlagTropBienDefExcl.Checked := sfcFlagsIsIn(FLAG_TROP_BIEN_DEF, FCurrentPlayer.Conf.FiltreFlagsRapportExclu);
   menFlagTropBienDefIgnr.Checked := NoT(menFlagTropBienDefIncl.Checked or menFlagTropBienDefExcl.Checked);

   menFlagNivEspEleveIncl.Checked := sfcFlagsIsIn(FLAG_NIV_ESP_ELEVE, FCurrentPlayer.Conf.FiltreFlagsRapportInclu);
   menFlagNivEspEleveExcl.Checked := sfcFlagsIsIn(FLAG_NIV_ESP_ELEVE, FCurrentPlayer.Conf.FiltreFlagsRapportExclu);
   menFlagNivEspEleveIgnr.Checked := NoT(menFlagNivEspEleveIncl.Checked or menFlagNivEspEleveExcl.Checked);

   menFlagNeJamaisAttackIncl.Checked := sfcFlagsIsIn(FLAG_NE_JAMAIS_ATTACK, FCurrentPlayer.Conf.FiltreFlagsRapportInclu);
   menFlagNeJamaisAttackExcl.Checked := sfcFlagsIsIn(FLAG_NE_JAMAIS_ATTACK, FCurrentPlayer.Conf.FiltreFlagsRapportExclu);
   menFlagNeJamaisAttackIgnr.Checked := NoT(menFlagNeJamaisAttackIncl.Checked or menFlagNeJamaisAttackExcl.Checked);

   menFlagPouleDorIncl.Checked := sfcFlagsIsIn(FLAG_POULE_AUX_OEUFS_DOR, FCurrentPlayer.Conf.FiltreFlagsRapportInclu);
   menFlagPouleDorExcl.Checked := sfcFlagsIsIn(FLAG_POULE_AUX_OEUFS_DOR, FCurrentPlayer.Conf.FiltreFlagsRapportExclu);
   menFlagPouleDorIgnr.Checked := NoT(menFlagPouleDorIncl.Checked or menFlagPouleDorExcl.Checked);

   menFlagTropPeuDevIncl.Checked := sfcFlagsIsIn(FLAG_MODE_TROP_PEUDEV, FCurrentPlayer.Conf.FiltreFlagsRapportInclu);
   menFlagTropPeuDevExcl.Checked := sfcFlagsIsIn(FLAG_MODE_TROP_PEUDEV, FCurrentPlayer.Conf.FiltreFlagsRapportExclu);
   menFlagTropPeuDevIgnr.Checked := NoT(menFlagTropPeuDevIncl.Checked or menFlagTropPeuDevExcl.Checked);


   
   menFiltreTousElementPresent.Checked    := FCurrentPlayer.Conf.FiltrePresenceTousDefaut;
   menFiltreTousElementNonPresent.Checked := NoT(menFiltreTousElementPresent.Checked);

   menFlagAucunIncl.Checked := FCurrentPlayer.Conf.FiltreFlagsAucunRapportInclu;
   menFlagAucunExcl.Checked := NoT(menFlagAucunIncl.Checked);


   menFiltreToutesConditionsRemplies.Checked := FCurrentPlayer.Conf.FiltreInclusionMethodAllVerif;
   menFiltreAuMoinsUneCondRemplie.Checked := NoT(menFiltreToutesConditionsRemplies.Checked);

   menFlagInactifIncl.Checked := sfcFlagsIsIn(CNT_GALAXIE_FLAGS_INACTIF_2SEMAINES, FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu) or sfcFlagsIsIn(CNT_GALAXIE_FLAGS_INACTIF_4SEMAINES, FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu);
   menFlagInactifExcl.Checked := sfcFlagsIsIn(CNT_GALAXIE_FLAGS_INACTIF_2SEMAINES, FCurrentPlayer.Conf.FiltreFlagsGalaxieExclu) or sfcFlagsIsIn(CNT_GALAXIE_FLAGS_INACTIF_4SEMAINES, FCurrentPlayer.Conf.FiltreFlagsGalaxieExclu);
   menFlagInactifIgnr.Checked := NoT(menFlagInactifIncl.Checked or menFlagInactifExcl.Checked);

   menFlagVacancesIncl.Checked := sfcFlagsIsIn(CNT_GALAXIE_FLAGS_MODE_VACANCES, FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu);
   menFlagVacancesExcl.Checked := sfcFlagsIsIn(CNT_GALAXIE_FLAGS_MODE_VACANCES, FCurrentPlayer.Conf.FiltreFlagsGalaxieExclu);
   menFlagVacancesIgnr.Checked := NoT(menFlagVacancesIncl.Checked or menFlagVacancesExcl.Checked);


   menFlagNewbzIncl.Checked := sfcFlagsIsIn(CNT_GALAXIE_FLAGS_PROTECTION_NOOB_TROPFAIBLE, FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu) or sfcFlagsIsIn(CNT_GALAXIE_FLAGS_PROTECTION_NOOB_TROPFORT, FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu);
   menFlagNewbzExcl.Checked := sfcFlagsIsIn(CNT_GALAXIE_FLAGS_PROTECTION_NOOB_TROPFAIBLE, FCurrentPlayer.Conf.FiltreFlagsGalaxieExclu) or sfcFlagsIsIn(CNT_GALAXIE_FLAGS_PROTECTION_NOOB_TROPFORT, FCurrentPlayer.Conf.FiltreFlagsGalaxieExclu);
   menFlagNewbzIgnr.Checked := NoT(menFlagNewbzIncl.Checked or menFlagNewbzExcl.Checked);


   menFlagPlaneteDetruiteIncl.Checked := sfcFlagsIsIn(CNT_GALAXIE_FLAGS_PLANETE_NON_OCCUPEE, FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu) or sfcFlagsIsIn(CNT_GALAXIE_FLAGS_ASTEROIDES, FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu);
   menFlagPlaneteDetruiteExcl.Checked := sfcFlagsIsIn(CNT_GALAXIE_FLAGS_PLANETE_NON_OCCUPEE, FCurrentPlayer.Conf.FiltreFlagsGalaxieExclu) or sfcFlagsIsIn(CNT_GALAXIE_FLAGS_ASTEROIDES, FCurrentPlayer.Conf.FiltreFlagsGalaxieExclu);
   menFlagPlaneteDetruiteIgnr.Checked := NoT(menFlagPlaneteDetruiteIncl.Checked or menFlagPlaneteDetruiteExcl.Checked);

   menFlagJoueurBloqueIncl.Checked := sfcFlagsIsIn(CNT_GALAXIE_FLAGS_USER_BLOQUE, FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu);
   menFlagJoueurBloqueExcl.Checked := sfcFlagsIsIn(CNT_GALAXIE_FLAGS_USER_BLOQUE, FCurrentPlayer.Conf.FiltreFlagsGalaxieExclu);
   menFlagJoueurBloqueIgnr.Checked := NoT(menFlagJoueurBloqueIncl.Checked or menFlagJoueurBloqueExcl.Checked);


   menFiltresLuneExclure.Checked      := false;
   menFiltresLuneInclure.Checked      := false;
   menFiltresLuneAfficheOnly.Checked  := false;

   case FCurrentPlayer.Conf.FiltreLuneState of
      CNT_FILTRE_LNE_STATE_EXCLURE: begin
             menFiltresLuneExclure.Checked      := true;
          end;

      CNT_FILTRE_LNE_STATE_INCLURE: begin
             menFiltresLuneInclure.Checked      := true;
          end;

      CNT_FILTRE_LNE_STATE_LUNE_SEULEMENT: begin
             menFiltresLuneAfficheOnly.Checked  := true;
          end;

   end;




   UpdateFiltreeItem;
   UpdateAllSpec(sgFiltrer, FBaseFiltree);

end;

procedure TfrmRapportHistorique.EnableOrDisableWebActionButton(bValeur: boolean);
begin
    cmdSondageStart.Enabled       := bValeur;
    cmdMessageListGet.Enabled     := bValeur;

    cmdSpiderGalaxieScan.Enabled  := bValeur;
    cmdSpiderStatsScan.Enabled    := bValeur;

    cmdViewAppercuListMsg.Enabled := bValeur;
    cmdAttaqueDoIt.Enabled        := bValeur;

    cmdChangePlaneteAndUpdateVaisseauxList.Enabled := bValeur;
    menMettreAJourLempire.Enabled := bValeur;


    cmdConstructionMaj.Enabled  := bValeur;
    cmdRessourceCalculer.Enabled := bValeur;
    cmdRessourcesUpdate.Enabled := bValeur;

    cmdEffectuerTransportMassif.Enabled := bValeur;

end;

procedure TfrmRapportHistorique.menActionEnleverClick(Sender: TObject);
begin
    if FCurrPlayerCurrPlanete = nil then exit;

    if FLastLigneSelectPlaneteScript > 0 then begin
       FCurrPlayerCurrPlanete.cActions.Delete(FLastLigneSelectPlaneteScript - 1);


       // Met à jour l'affichage
       AfficheActionInGrid(sgElementsAction, FCurrPlayerCurrPlanete.cActions);

    end;
end;

procedure TfrmRapportHistorique.EnableOrDisableBDDButton(bValeur: boolean);
begin
    cmdSondageInactifs.Enabled   := bValeur;
    cmdSondagePoints.Enabled     := bValeur;
end;

function TfrmRapportHistorique.SpiderChangePlaneteToGalaxieScanSelected: integer;
begin
    Result := SpiderChangePlaneteToThis(SpiderGalaxieGetSelectedPlanete);
end;

function TfrmRapportHistorique.SpiderChangePlaneteToThis(Planete: TPlanetLocation): integer;
begin

    if Planete.Galaxie < 1 then begin
       Result := -1;
       exit;
    end;

    Result := FCurrentPlayer.ChangePlanete(Planete);

    FCurrPlayerCurrPlanete := FCurrentPlayer.curPlanete;

    if Result = 0 then begin
       // changement inutile
       Result := 1;
    end;

end;

procedure TfrmRapportHistorique.SpiderGalaxieSetRangeFromCurrent(Distance: integer);
begin
    SpiderGalaxieSetRange(SpiderGalaxieGetSelectedPlanete, Distance);
end;

procedure TfrmRapportHistorique.SpiderGalaxieSetRange(Planete: TPlanetLocation; Distance: integer);
begin
    if Planete.Galaxie < 1 then exit;

    // Les limites min et max des spinedit s'occuperont d'ajuster les valeurs
    // pour rester dans l'intervalle valide des systèmes solaires
    seGalaxieSystemeEnd.Value   := Planete.SystemSolaire + Distance;
    seGalaxieSystemeStart.Value := Planete.SystemSolaire - Distance;


    seSondageSystemEnd.Value   := Planete.SystemSolaire + Distance;
    seSondageSystemStart.Value := Planete.SystemSolaire - Distance;

end;

function SpiderGalaxieTextPlaneteToLocation(sText: string): TPlanetLocation;
begin
    Result := msgSpiderGalaxieTextPlaneteToLocation(sText);
end;

function TfrmRapportHistorique.SpiderGalaxieGetSelectedPlanete: TPlanetLocation;
var xText: string;
begin
    xText := cbGalaxieScanPlanete.Text;

    Result := SpiderGalaxieTextPlaneteToLocation(xText);
end;


procedure TfrmRapportHistorique.LoadPlaneteInComboAndMenuFromProfils;
var i: integer;
    sStrPlanete: string;
    ItemMenu: TMenuItem;
begin

    cbGalaxieScanPlanete.Items.Clear;
    //menChangerPlanete.Clear;
    cbSondagePlanete.Items.Clear;

    cbListAttaquePlaneteDepart.Items.Clear;
    cbListAttaquePlaneteSondage.Items.Clear;


    cbMassiveTransportDest.Items.Clear;
    lstcMassiveTransportPlanetes.Items.Clear;
    

    if FCurrentPlayer.Conf.PlanetesList.Count = 0 then begin
     (*  ItemMenu := TMenuItem.Create(menChangerPlanete);
       ItemMenu.Caption := 'Vos planètes';
       ItemMenu.Enabled := false;
       menChangerPlanete.Add(ItemMenu);
       *)
       FCurrentPlayer.Conf.SondageLastPlaneteSel := -1;
       exit;
    end;

    for i := 0 to FCurrentPlayer.Conf.PlanetesList.Count - 1 do begin
       sStrPlanete := FCurrentPlayer.Conf.PlanetesList.Strings[i];

       cbGalaxieScanPlanete.Items.Add(sStrPlanete);
       cbSondagePlanete.Items.Add(sStrPlanete);
       cbAttaquePlanete.Items.Add(sStrPlanete);

       cbListAttaquePlaneteDepart.Items.Add(sStrPlanete);
       cbListAttaquePlaneteSondage.Items.Add(sStrPlanete);

       cbMassiveTransportDest.Items.Add(sStrPlanete);
       lstcMassiveTransportPlanetes.Items.Add(sStrPlanete);

       (*
       ItemMenu := TMenuItem.Create(menChangerPlanete);
       ItemMenu.Caption := sStrPlanete;
       ItemMenu.Enabled := true;
       //ItemMenu.OnClick := proc;     // Associe la procédure de changement
       menChangerPlanete.Add(ItemMenu);
           *)
    end;

    if FCurrentPlayer.Conf.SondageLastPlaneteSel < 0 then
       FCurrentPlayer.Conf.SondageLastPlaneteSel := 0;

    cbGalaxieScanPlanete.ItemIndex            := FCurrentPlayer.Conf.SondageLastPlaneteSel;
    cbSondagePlanete.ItemIndex                := FCurrentPlayer.Conf.SondageLastPlaneteSel;
    cbListAttaquePlaneteSondage.ItemIndex     := FCurrentPlayer.Conf.SondageLastPlaneteSel;

    cbAttaquePlanete.ItemIndex            := FCurrentPlayer.Conf.AttackLastPlanete;
    cbListAttaquePlaneteDepart.ItemIndex  := FCurrentPlayer.Conf.AttackLastPlanete;
    cbMassiveTransportDest.ItemIndex      := FCurrentPlayer.Conf.AttackLastPlanete;

end;

function TfrmRapportHistorique.SpiderDoLogin: integer;
label lSkipProtection;
var r: integer;
    cPlanete: PLinkOtherPlanete;
    ItemMenu: TMenuItem;
    sStrPlanete: string;
    lSecu: int64;
    bLoginSuccess: boolean;

    sDirectLoginPage, sDCFile: string;
    sDCStream: TFileStream;
begin


    Result := 0;
    if menSpiderLogin.Enabled = false then begin
       Result := -1;
       exit;
    end;



    FCurrentPlayer.Clear(false);

    FCurrPlayerCurrPlanete   := nil;
    FCurrPlayerCurrPlanetForConstruction := nil;






    {$IFDEF DEBUG}
        FCurrentPlayer.DebugProc := Status;
    {$ENDIF}


    // Désactive tous les boutons qui permettent le login
    menSpiderLogin.Enabled := false;



    FCurrentPlayer.StatusGalaxieProc := Status;

    FCurrentPlayer.Conf.SondageLastPlaneteSel :=  cbGalaxieScanPlanete.ItemIndex;

    cbGalaxieScanPlanete.Items.Clear;
    //menChangerPlanete.Clear;
    cbSondagePlanete.Items.Clear;
    FCurrentPlayer.Conf.PlanetesList.Clear;
    cbAttaquePlanete.Items.Clear;


    // effectue dès maintenant l'association des évènements
    // le reste s'enclenche plus loin
    FCurrentPlayer.AlerteAttaqueGestion.OnAttackNewDetected := OnAttackNouvelle;
    FCurrentPlayer.AlerteAttaqueGestion.OnAttackAnnule      := OnAttackAnnule;


    FCurrentPlayer.LoginUseLocalWebPage := false;
    FCurrentPlayer.LoginLocalWebPage    := '';

    if optDLSpecial.Checked or optDLCache.Checked then begin

       if optDLSpecial.Checked then begin
          sDCFile := txtDirectLoginPageWeb.Text;

       end else if optDLCache.Checked then begin
          sDCFile := FCurrentPlayer.GetCacheLoginPagePath;
       end;

       if pos('\', sDCFile) < 1 then begin
          sDCFile := IncludeTrailingPathDelimiter(ExtractFileDir(Application.ExeName)) + sDCFile;
       end;

       if FileExists(sDCFile) then begin

          Status(format(_('Fichier DirectLogin: %s'), [sDCFile]));
          try
            sDCStream := TFileStream.Create(sDCFile, fmOpenRead);

            SetLength(FCurrentPlayer.LoginLocalWebPage, sDCStream.Size);

            sDCStream.Read(FCurrentPlayer.LoginLocalWebPage[1], sDCStream.Size);

            sDCStream.Free;

            FCurrentPlayer.LoginUseLocalWebPage := true;

          except
            Status(_('Lecture de la page de direct login impossible'));
            if sDCStream <> nil then begin
               sDCStream.Free;
            end;
          end;



       end else begin
          Status(format(_('Direct login file inexistant: %s'), [sDCFile]));
       end;

    end;





    r := FCurrentPlayer.ProceedLogin;
    lSecu := 0;
    bLoginSuccess := false;

    if r <= 0 then begin
       // echec de login
       Status(format(_('Echec de login - r = %d'), [r]));

    end else begin
       Status(_('Login réussi.'));
       Result := 1;

       lSecu := FCurrentPlayer.DifferenceHeureLocaleHeureServeur;


       //FCurrentPlayer.cParsing.pApercu



       sStrPlanete := FCurrentPlayer.cParsing.pHeader.PlaneteNom + ' - ' + FCurrentPlayer.cParsing.pHeader.PlaneteStr;

       // On ajoute que dans le profil, on charge ensuite dans les combobox et menu à partir du profil
       FCurrentPlayer.Conf.PlanetesList.Add(sStrPlanete);

       if (lSecu < 0) then
           lSecu := -1 * lSecu;

       if FCurrentPlayer.cParsing.pHeader.AutrePlanete.Count > 0 then begin
          for r := 0 to FCurrentPlayer.cParsing.pHeader.AutrePlanete.Count - 1 do begin
             cPlanete := FCurrentPlayer.cParsing.pHeader.AutrePlanete.Items[r];

             sStrPlanete := cPlanete.Nom + ' - ' + mbtPlanetLocationToStr(cPlanete.Location);

             FCurrentPlayer.Conf.PlanetesList.Add(sStrPlanete);
          end;

       end;

       cbGalaxieScanPlanete.ItemIndex := FCurrentPlayer.Conf.SondageLastPlaneteSel;
       cbSondagePlanete.ItemIndex     := FCurrentPlayer.Conf.SondageLastPlaneteSel;

       EnableOrDisableWebActionButton(true);

       if FInfosBaseDeDonneCharge = false then begin
          // aucune base de données chargées...

       end;

       
       timAttackNotificationAndOnTimer.Interval := 1000;


       // TODO: Afficher les messages parsés dans aperçu
       //UpdateMsgList(sgGridMsgList, FCurrentPlayer.cAppercu.MsgList);

       Status(format(_('Différence de temps avec le serveur ogame: %d secondes'), [FCurrentPlayer.DifferenceHeureLocaleHeureServeur])); // + IntToStr(FCurrentPlayer.DifferenceHeureLocaleHeureServeur) + ' secondes');
       bLoginSuccess := true;
    end;

    LoadPlaneteInComboAndMenuFromProfils;

    Sleep(1);
    Application.ProcessMessages;



    // sauvegarde le profil
    FCurrentPlayer.Conf.SaveToFile('');

    
    /////////////////////////////////////////////////////
    // Modifier la date unix à chaque prolongement
    //
    // mIRC: $ctime(4/07/2006 15:27:14)  = 1152023234
    // mIRC: $ctime(3/08/2006 14:37:11)  = 1154612231
    // mIRC: $ctime(3/09/2006 14:07:11)  = 1157288831
    // mIRC: $ctime(5/10/2006 10:57:39)  = 1160042259
    // mIRC: $ctime(7/10/2006 19:07:32)  = 1160244452
    // mIRC: $ctime(7/11/2006 19:07:32)  = 1162922852
    // mIRC: $ctime(3/12/2006 11:40:17)  = 1165142417
    // mIRC: $ctime(4/02/2007 10:22:13)  = 1170580933
    // mIRC: $ctime(6/05/2007 10:22:13)  = 1178443333
    // mIRC: $ctime(4/06/2007 15:22:13)  = 1180966933
    // ---- eBay: break de diffusion... pas fait, mais ralongé jusqu'au 21
    // mIRC: $ctime(21/07/2007 08:15:30) = 1185002130
    // mIRC: $ctime(04/09/2007 10:05:41)  = 1188896741
    // mIRC: $ctime(01/01/2008 12:31:23)  = 1199187083
    // mIRC: $ctime(01/01/2009 12:31:23)  = 1230809483


    if (lSecu > 864000) or (FCurrentPlayer.cParsing.pApercu.ServeurDate > 1230809483) then begin
       // plus de 10jours de difference avec le serveur

       {$IFDEF DEBUGPROTECTION}
             Status('PROTECTION >> Intervalle de difference trop grand');
       {$ENDIF}



       lSecu := 25714 + lSecu mod 18000;

       {$IFDEF DEBUGPROTECTION}
           Status('PROTECTION >> SpiderDoLogin - Secu Exp: Fermeture dans: ' + IntToStr(lSecu) + ' secondes');
       {$ENDIF}

       {$IFDEF NO_TIME_LIMIT}
           // pas de limite dans le temps
           goto lSkipProtection;
       {$ENDIF}



       if FDynTimer = nil then begin

          {$IFDEF DEBUGPROTECTION}
             Status('PROTECTION >> SpiderDoLogin - Creation timer');
          {$ENDIF}

          FDynTimer := TTimer.Create(nil);
          FDynTimer.OnTimer := tOnTimerDynClose;
          FDynTimer.Interval := lSecu;

          sStrPlanete := GetFileFromScanForThisGalaxie(7, lSecu, tbdRapports);

          if length(sStrPlanete) = 0 then begin
             FDynTimer.Interval := FDynTimer.Interval - 18;
          end;


       end else begin
          FDynTimer.Enabled := false;
          FDynTimer.OnTimer := tOnTimerDynClose;

          FDynTimer.Interval := 0;
          cmdSondageStart.Enabled := true;

          FDynTimer.Interval := lSecu;
          FDynTimer.Enabled := true;
       end;


          {$IFDEF DEBUGPROTECTION}
             Status('PROTECTION >> SpiderDoLogin - FDynTimer.Interval: ' + IntToStr(FDynTimer.Interval));
          {$ENDIF}

    end;


    
lSkipProtection:

    if bLoginSuccess then begin
       //
       // Alerte d'attaque
       //


       if FCurrentPlayer.Conf.AlerteAttEnableOnLogin then begin
          // simule le click
          cmdAlerteAttActiverClick(nil);
       end else begin
          cmdAlerteAttDesactiverClick(nil);
       end;


       if FCurrentPlayer.ExistOfficier then begin
          // le robot a été patché ?
          {$IFDEF OFFICIER_OK}
             if FCurrentPlayer.AllowToWorkWithOfficier = false then begin
                EnableOrDisableWebActionButton(false);
             end;
          {$ELSE}
             EnableOrDisableWebActionButton(false);
          {$ENDIF}

       end;

       
       //
       // Auto relogin
       //


       if FCurrentPlayer.allPlanetes.Count > 0 then begin
          switchPlanet.TabIndex := 0;

          FCurrentPlayer.Lock;

          FCurrPlayerCurrPlanete := FCurrentPlayer.allPlanetes.Items[0];
          FCurrPlayerCurrPlanetForConstruction := FCurrPlayerCurrPlanete;
          LoadPlanetInForm(FCurrPlayerCurrPlanetForConstruction);

          FCurrentPlayer.UnLock;
       end;

       FCurrentPlayer.ConstructionAutoEnable := chkActiveModuleGestionAuto.Checked;
       FCurrentPlayer.ListeDattaqueActive    := chkListeDattenteTraitementActive.Checked;


       if Global_LocalSetting.ConfGetBool(CNT_LOCALSETTING_BOOL_DL_NewsAUTO) = true then begin

          if Global_LocalSetting.ConfGet64(CNT_LOCALSETTING_DATE_LastAUTODlNews) < (DateTimeToUnix(Now) - (3600 * 7)) then begin
             // on peut dl les news

             Global_LocalSetting.ConfSet64(CNT_LOCALSETTING_DATE_LastAUTODlNews, DateTimeToUnix(Now));

             cmdInfosDLNewsClick(nil);

             Global_LocalSetting.SaveToFile('', [lsoEnteteValues]);

          end;

       end;



    end else begin
       Status(_('Login échec...'));
    end;


    Status(_('Profil sauvegardé'));

    // Réactive tout les boutons qui permettent le login
    menSpiderLogin.Enabled := true;
end;

function DateHeureCreationFichier2(fichier: string): TDateTime;
begin
  // FileDateToDateTime transforme une date de type dos en format TDateTime
  Result := FileDateToDateTime(FileAge(fichier));
end;


function DateHeureCreationFichier1(fichier: string): TDateTime;
var SearchRec:TSearchRec;
    Resultat:longint;
begin

  Result   := 0;

  Resultat := FindFirst(fichier, FaAnyFile, SearchRec);
  if Resultat = 0 then
     // FileDateToDateTime transforme une date de type dos en format TDateTime
     Result := FileDateToDateTime(SearchRec.Time);

  FindClose(SearchRec);

end;


procedure TfrmRapportHistorique.SetFileLabelFromGalaxie(Galaxie: integer);
var FichierRapport, FichierGalaxie: string;
begin

    if (Galaxie < 1) or (Galaxie > 50) then begin
       lblProfilFichierRapportDB.Caption := _('Hors limite');
       lblProfilFichierRapportDB.Font.Color := clRed;

       lblProfilFichierGalaxyDB.Caption := _('Hors limite');
       lblProfilFichierGalaxyDB.Font.Color := clRed;
       exit;
    end;

    // Fait la galaxie dès maintenant
    FichierGalaxie := GetFileFromScanForThisGalaxie(FCurrentPlayer.Conf.Univers, Galaxie, tbdGalaxie);

    if FichierGalaxie <> '' then begin
       lblProfilFichierGalaxyDB.Caption := ExtractFileName(FichierGalaxie);
       lblProfilFichierGalaxyDB.Font.Color := clTeal;
    end else begin
       lblProfilFichierGalaxyDB.Caption := _('Introuvable');
       lblProfilFichierGalaxyDB.Font.Color := clPurple;
    end;




    FichierRapport := FCurrentPlayer.Conf.GetRapportDB(Galaxie);


    if FichierRapport <> '' then begin
       // Existe dans le profil, on le color en vert
       lblProfilFichierRapportDB.Caption := ExtractFileName(FichierRapport);
       lblProfilFichierRapportDB.Font.Color := clTeal;
       exit;
    end;


    // Sinon scan les fichier dans le dossier
    FichierRapport := GetFileFromScanForThisGalaxie(FCurrentPlayer.Conf.Univers, Galaxie, tbdRapports);

    if FichierRapport <> '' then begin
       lblProfilFichierRapportDB.Caption := ExtractFileName(FichierRapport) + ' ?';
       lblProfilFichierRapportDB.Font.Color := clPurple;
       exit;
    end;

    
    // inexistant, on le créé
    FichierRapport := format(CNT_RAPPORT_DB_FILE_FORMAT, [FCurrentPlayer.Conf.Univers, Galaxie]);
    lblProfilFichierRapportDB.Caption := FichierRapport;
    lblProfilFichierRapportDB.Font.Color := clMaroon;





end;


function TfrmRapportHistorique.GetFileFromScanForThisGalaxie(Univers, Galaxie: integer; BDDType: TFichierBDDType): string;
begin

    if BDDType = tbdRapports then begin
       //scanDir.Filtre := '*.od';
       //scanDir.Dossier := FDossierDB;
       Result := FDossierDB + format(CNT_RAPPORT_DB_FILE_FORMAT, [Univers, Galaxie]);

       if FileExists(Result) = false then begin
          Result := '';
       end;

    end else if BDDType = tbdGalaxie then begin
       //scanDir.Filtre := '*.ug';
       //scanDir.Dossier := FDossierGalaxieDB;

       Result :=FDossierGalaxieDB +  format(CNT_GALAXIE_DB_FILE_FORMAT, [Univers, Galaxie]);

       if FileExists(Result) = false then begin
          Result := '';
       end;

    end else begin
       // inconnu
       Result := '';
       exit;
    end;

(*  scanDir.MaxPenetration := 30; scanDir.SousDossier := true;

    FScanGalaxie := Galaxie; FScanUnivers := FCurrentPlayer.Conf.Univers; FScanFileFound := '';

    FScanDB  := TCollectionRapportHead.Create; FScanDB.LoadOnlyHeader := true;

    scanDir.Execute; FScanDB.Free; FScanDB := nil;

    Result := FScanFileFound; *)
end;


procedure TfrmRapportHistorique.RefreshOwnPoints;
var pe: PPlayerStats;
begin

    if FCurrentPlayer = nil then begin
       lblProfilPointsGlobal.Caption  := _('Joueur inconnu');
       lblProfilPointsFlottes.Caption := _('Joueur inconnu');
       exit;
    end;

    pe := FCurrentPlayer.StatsPlayer.Get_Pointeur(FCurrentPlayer.Conf.Pseudo);
    if pe <> nil then begin
       lblProfilPointsGlobal.Caption := format(_('%s points'), [sfcFormatStrToMilliers(pe.Points)]);

    end else begin
       lblProfilPointsGlobal.Caption := _('Inconnu');
    end;
    lblScanUserPointsGlobaux.Caption := lblProfilPointsGlobal.Caption;

    pe := FCurrentPlayer.StatsPlayerFlottes.Get_Pointeur(FCurrentPlayer.Conf.Pseudo);
    if pe <> nil then begin
       lblProfilPointsFlottes.Caption := format(_('%s points'), [sfcFormatStrToMilliers(pe.Points)]);

    end else begin
       lblProfilPointsFlottes.Caption := _('Inconnu');
    end;
    lblScanUserPointsFlottes.Caption := lblProfilPointsFlottes.Caption;


end;

procedure TfrmRapportHistorique.LoadProfilInFormLimitation;
begin
    // on modifie ici tout ce qui peut etre change par l'édition de la configuration
    // du profil

    
    seSondageSystemEnd.MaxValue := FCurrentPlayer.Conf.UniversNbSystemSolaireParGalaxy;

    ProxyUpdateLabel;
end;

procedure TfrmRapportHistorique.LoadProfilInForm;
begin

  //  txtProfilPseudo.Text := FCurrentPlayer.Conf.Pseudo;
  //  seProfilUni.Value := FCurrentPlayer.Conf.Univers;


  
    // Charge les informations de planètes
    // et sélectionne les dernières planètes qui ont été utilisés
    LoadPlaneteInComboAndMenuFromProfils;



    seSondageSystemStart.Value := FCurrentPlayer.Conf.SondageSystemRangeStart;
    seSondageSystemEnd.Value   := FCurrentPlayer.Conf.SondageSystemRangeEnd;

    seGalaxieSystemeStart.Value := FCurrentPlayer.Conf.SondageSystemRangeStart;
    seGalaxieSystemeEnd.Value   := FCurrentPlayer.Conf.SondageSystemRangeEnd;

    seSondageDureePourEtrePrisEnCompte.Value := FCurrentPlayer.Conf.SondageDureeToBeConsideredAsRecent;
    seSondageIgnoreDelayLastSondage.Value    := FCurrentPlayer.Conf.SondageDureeToDontBeSondeANouveau;

    seSpiderGalaxieDureeRecent.Value := FCurrentPlayer.Conf.SondageDureeToBeConsideredAsRecent;



    seSondageStatsLimitGlobales.Value       := FCurrentPlayer.Conf.SondageLimitStatsGlobal;
    seSondageStatsLimitFlottes.Value        := FCurrentPlayer.Conf.SondageLimitStatsFlottes;

    chkSondagePointGlobalNonClasse.Checked  := FCurrentPlayer.Conf.SondageLimitStatsGlobalInclureNonClasse;
    chkSondagePointFlottesNonClasse.Checked := FCurrentPlayer.Conf.SondageLimitStatsFlottesInclureNonClasse;


    



    
    // désactive la construction automatique
    chkActiveModuleGestionAuto.Checked       := false;
    chkListeDattenteTraitementActive.Checked := false;


    LoadProfilInFormLimitation;
    

    // initialise les grilles
    InitGrille(sgPlanetesRecentes);
    InitGrille(sgPlanetesPoulesDor);
    InitGrille(sgFiltrer);

    RefreshOwnPoints;
end;

procedure TfrmRapportHistorique.StatusAlerteAtt(const Msg: string);
begin
    Status(_('Alerte d''attaque - ') + Msg);
end;

procedure TfrmRapportHistorique.StatusNews(const Msg: string);
begin
    txtNewsAffichage.Lines.Add(Msg);
    Status(_('News - ') + Msg);
end;

procedure TfrmRapportHistorique.Status(const Msg: string);
begin
    txtDebug1.Lines.Add(DateTimeToStr(Now) + ' - ' + Msg);

    if FFileStatusLogEnable then begin
       WriteLn(FFileStatusLog, DateTimeToStr(Now) + ' - ' + Msg);
       Flush(FFileStatusLog);
    end;



    if FStatusSocket <> nil then begin
       try
          FStatusSocket.SendStr(DateTimeToStr(Now) + ' - ' + Msg + '<br>' + CNT_CRLF);
       except
          // La connexion a du être fermé
          FStatusSocket := nil;
       end;
       
    end;
end;

procedure TfrmRapportHistorique.StatusSockets(const Msg: string);
begin
    Status(_('Socket - ') + Msg);
end;





procedure TfrmRapportHistorique.AfficheResRowInGrid(Grille: TAdvStringGrid; Res: TList; cRes: TOGRessourceAll; DoClear: boolean);
var CurrRes: POGResUsed;
    lRes: TOGResUsed;
    i, j: integer;
    cProd: TOGRessourceAll;
begin

    if Res.Count = 0 then exit;

    if Grille.RowCount > 1 then begin
       if DoClear then begin
          Grille.RemoveRows(2, Grille.RowCount - 2);
          j := 0;
       end else
          j := 1;

    end else begin
        j := 0;
        
    end;


    for i := 0 to Res.Count - 1 do begin
        CurrRes := Res.Items[i];

        msgUpdateRessourcesProdListRow(Grille, CurrRes^, cRes, i + j);

    end;

    cProd := mcrGetCalculTotalParHeure(Res);

    lRes.IdOpt       := _('Total');
    lRes.prMetal     := cProd.Metal;
    lRes.prCristal   := cProd.Cristal;
    lRes.prDeuterium := cProd.Deuterium;
    lRes.prEnergie   := 0;
    lRes.csEnergieUsed  := 0;
    lRes.csEnergieAllow := 0;
    lRes.Activite    := -1;
    lRes.ActiviteForOptimization := -1;

    msgUpdateRessourcesProdListRow(Grille, lRes, cRes, 1);

end;





procedure TfrmRapportHistorique.AfficheActionInGrid(Grille: TAdvStringGrid; Action: TCollectionElementActionItem);
var i, r: integer;
    pE : PElementActionItem;
begin

    if Action.Count = 0 then begin
       if Grille.RowCount > 2 then
          Grille.RemoveRows(2, Grille.RowCount - 2);

       Grille.Cells[0, 1] := '';
       Grille.Cells[1, 1] := '';
       Grille.Cells[2, 1] := '';
       Grille.Cells[3, 1] := '';
       Grille.Cells[4, 1] := '';

       exit;
    end;

    // Supprime les lignes super flu
    if Grille.RowCount > Action.Count then begin
       Grille.RemoveRows(2, Grille.RowCount - 1 - Action.Count);
    end;

    r := 1;

    for i := 0 to Action.Count - 1 do begin

        if Grille.RowCount = r then begin
           Grille.AddRow;
           r := Grille.RowCount - 1;
        end;


        pE := Action.Items[i];
        msgUpdateSimpleActionScriptRow(Grille, r, pE, FGidToStr);


        Inc(r);
    end;

end;



procedure TfrmRapportHistorique.LoadPlanetInForm(Planete: TPlaneteInfo);
begin

    // Calcul les stats
    Planete.EvaluationDisponibiliteConstruction;
    
    // Batiments
    sggUpdateGidElements(sgElementsConstructible, Planete.cElements, Planete.FLastRessources, Planete.pRessourcesProd, true);

    // Ressources
    AfficheResRowInGrid(sgRessourcesProd, Planete.cRessources, Planete.FLastRessources, true);

    // Actions
    AfficheActionInGrid(sgElementsAction, Planete.cActions);

    lblCurrPlaneteCoord.Caption := Planete.pLocationStr;
end;

procedure TfrmRapportHistorique.RefreshPlanetGridAutoConstruction(Joueur: TPlayerGestion);
var lPlanet: TListPlanet;
    i, c: integer;
    cPlanet: TPlaneteInfo;
    cTab: TTabCollectionItem;
begin

    lPlanet := Joueur.allPlanetes;

    if (lPlanet = nil) or (lPlanet.Count = 0) then  begin
       exit;
    end;

    // Supprime les tab super flu
    while (switchPlanet.AdvTabs.Count > lPlanet.Count) do begin
       switchPlanet.AdvTabs.Delete(switchPlanet.AdvTabs.Count - 1);
    end;

    c := 1;
    for i := 0 to lPlanet.Count - 1 do begin


        if switchPlanet.AdvTabs.Count < c then begin
           switchPlanet.AdvTabs.Add;
        end;

        cTab := switchPlanet.AdvTabs.Items[i];



        cPlanet := lPlanet.Items[i];

        cTab.Caption := cPlanet.FNom;
        Inc(c);
    end;

    
    if FCurrentPlayer.allPlanetes.Count = 1 then begin
       FCurrPlayerCurrPlanete := FCurrentPlayer.allPlanetes.Items[0];
       FCurrPlayerCurrPlanetForConstruction := FCurrPlayerCurrPlanete;
       LoadPlanetInForm(FCurrPlayerCurrPlanetForConstruction);
    end;

(*
    //Debug('Production totale:');
    AfficheTOGRessourceAll(FCurrentPlayer.allPlanetes.ProductionTotale);

    //Debug('Ressources totales last:');
    AfficheTOGRessourceAll(FCurrentPlayer.allPlanetes.RessourcesTotale);

    //Debug('Ressources totales estimées:');
    AfficheTOGRessourceAll(FCurrentPlayer.allPlanetes.RessourcesEstimTotale);
*)

end;

procedure TfrmRapportHistorique.playerOnItemsCostChange(Joueur: TPlayerGestion; Planete: TPlaneteInfo);
begin
    if FCurrPlayerCurrPlanetForConstruction = Planete then begin
       FCurrentPlayer.Lock;
       LoadPlanetInForm(FCurrPlayerCurrPlanetForConstruction);

       // Raffraichi les données de l'empire
       RefreshPlanetGrid(FCurrentPlayer, true);

       FCurrentPlayer.UnLock;
    end;
end;


procedure TfrmRapportHistorique.switchPlanetClick(Sender: TObject);
var i: integer;
begin
    if FCurrentPlayer = nil then begin
       exit;
    end;

    i := switchPlanet.TabIndex;

    if i < 0 then exit;
    if i >= FCurrentPlayer.allPlanetes.Count then exit;

    FCurrentPlayer.Lock;

    FCurrPlayerCurrPlanete := FCurrentPlayer.allPlanetes.Items[i];
    FCurrPlayerCurrPlanetForConstruction := FCurrPlayerCurrPlanete;
    LoadPlanetInForm(FCurrPlayerCurrPlanetForConstruction);

    FCurrentPlayer.UnLock;

end;

procedure TfrmRapportHistorique.switchPlanetMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var i: integer;
begin
    if FCurrentPlayer = nil then begin
       exit;
    end;
    i := switchPlanet.TabIndex;

    if i < 0 then exit;
    if i >= FCurrentPlayer.allPlanetes.Count then exit;

    if FCurrentPlayer.allPlanetes.Count = 1 then begin
       FCurrentPlayer.Lock;

       FCurrPlayerCurrPlanete := FCurrentPlayer.allPlanetes.Items[i];
       FCurrPlayerCurrPlanetForConstruction := FCurrPlayerCurrPlanete;
       LoadPlanetInForm(FCurrPlayerCurrPlanetForConstruction);

       FCurrentPlayer.UnLock;
    end;

end;

procedure TfrmRapportHistorique.LoadStatsFileForUnivers(Uni: integer; bDejaPathConnu: boolean = false);
var //Dossier: string;
    iDiff: int64;
    StatsUniPath: string;
begin


    if FCurrentPlayer = nil then begin
       // impossible de charger les stats
       Status('LoadStatsFileForUnivers - ' + _('Joueur en cours invalide (nil)'));
       exit;
    end;

    //Status('LoadStatsFileForUnivers...');


    FCurrentPlayer.ClearStats;


    FCurrDate := DateTimetoUnix(Now);


    StatsUniPath := GetStatsUniPath;

    txtStatsUnivers.Caption := IntToStr(Uni);


    if DirectoryExists(StatsUniPath) then begin


        if bDejaPathConnu = false then begin
           // bDejaPathConnu permet de ne pas rechercher à nouveau les fichiers
           // lorsque l'on vient de mettre à jour les stats
           
           if FStatsGetFileRecent.GetFromDir(StatsUniPath) = false then begin
              // le fichier qui indique les stats récents n'existe pas
              // on va donc tous les parcourir
              FStatsGetFileRecent.ScanDir(StatsUniPath, Uni);

              // sauvegarde le résultat
              FStatsGetFileRecent.SetToDir(StatsUniPath);
           end;
        end;



        if FStatsGetFileRecent.FileStatsAll <> '' then begin
           FCurrentPlayer.StatsPlayer.LoadFromFile(FStatsGetFileRecent.FileStatsAll);

           iDiff := FCurrDate - FCurrentPlayer.StatsPlayer.DateCreation;
           lblStatsEtatGlobales.Caption := ESBDGetDureeStrings(iDiff, false, 3);
           lblStatsEtatGlobales.Font.Color := clTeal;
        end else begin
           Status(_('Fichier stats (all) introuvable'));


           lblStatsEtatGlobales.Caption := _('Introuvable');
           lblStatsEtatGlobales.Font.Color := clRed;
        end;

        if FStatsGetFileRecent.FileStatsFlottes <> '' then begin
           FCurrentPlayer.StatsPlayerFlottes.LoadFromFile(FStatsGetFileRecent.FileStatsFlottes);

           iDiff := FCurrDate - FCurrentPlayer.StatsPlayerFlottes.DateCreation;
           lblStatsEtatFlottes.Caption := ESBDGetDureeStrings(iDiff, false, 3);
           lblStatsEtatFlottes.Font.Color := clTeal;
        end else begin
           Status(_('Fichier stats (flottes) introuvable'));

           lblStatsEtatFlottes.Caption := _('Introuvable');
           lblStatsEtatFlottes.Font.Color := clRed;
        end;

        if FStatsGetFileRecent.FileStatsRecherche <> '' then begin
           FCurrentPlayer.StatsPlayerRecherche.LoadFromFile(FStatsGetFileRecent.FileStatsRecherche);

           iDiff := FCurrDate - FCurrentPlayer.StatsPlayerRecherche.DateCreation;
           lblStatsEtatRecherche.Caption := ESBDGetDureeStrings(iDiff, false, 3);
           lblStatsEtatRecherche.Font.Color := clTeal;
        end else begin
           Status(_('Fichier stats (recherches) introuvable'));

           lblStatsEtatRecherche.Caption := _('Introuvable');
           lblStatsEtatRecherche.Font.Color := clRed;
        end;

        RefreshOwnPoints;


    end else begin
        Status(_('Dossier stats de l''univers inexistant'));

        lblStatsEtatGlobales.Caption := _('Introuvable');
        lblStatsEtatGlobales.Font.Color := clRed;
           
        lblStatsEtatFlottes.Caption := _('Introuvable');
        lblStatsEtatFlottes.Font.Color := clRed;

        lblStatsEtatRecherche.Caption := _('Introuvable');
        lblStatsEtatRecherche.Font.Color := clRed;

    end;

    if frmInfoPlayer <> nil then begin
       frmInfoPlayer.SetStatsCollectionTotal(FCurrentPlayer.StatsPlayer);
       frmInfoPlayer.SetStatsCollectionFlottes(FCurrentPlayer.StatsPlayerFlottes);

       frmInfoPlayer.SetCurrentPlayerPointFlottes(FCurrentPlayer.Conf.LimitStFlotte);
       frmInfoPlayer.SetCurrentPlayerPointTotal(FCurrentPlayer.Conf.LimitStGlobal);
    end;

    //Status('LoadStatsFileForUnivers end');

end;

procedure TfrmRapportHistorique.InitForm;
var bValue: boolean;
begin
     gbPlanete.Caption := _('Informations');


     txtInfos.Lines.Clear;
     txtRapportLast.Lines.Clear;

     bValue := false;
     chkTropBienDef.Checked      := bValue;
     chkNivEspEleve.Checked      := bValue;
     chkNeJamaisAttaquer.Checked := bValue;
     chkPouleAuxOeufsDor.Checked := bValue;
     chkTropPeuDev.Checked       := bValue;

     chkNePasSonderPourCetteSession.Checked := bValue;
     chkPlaneteARecycler.Checked := bValue;
     chkPlaneteDejaRecycler.Checked := bValue;
end;


procedure TfrmRapportHistorique.memFlotteListEspionnerClick(Sender: TObject);
var pe: PFlotteListEnVoyage;
    peGalaxy: PGalaxiePlanete;
begin

    if FLastIndexSelectFlotteList < FCurrentPlayer.cFlotteVaisseaux.FlotteList.Count then begin
       pe := FCurrentPlayer.cFlotteVaisseaux.FlotteList.Items[FLastIndexSelectFlotteList];

       peGalaxy := FBase2DonneesPlanete.Get_Pointeur(pe.Arrivee);

       if peGalaxy <> nil then begin
          SondageCheckAndTryToAddThisCoord(pe.Arrivee, peGalaxy, false);
       end;


    end else begin
    
    end;
    
end;

procedure TfrmRapportHistorique.memRapportOnClick(Sender: TObject);
var cItem: TMenuItem;
    sRapport: string;
    cPosition: integer;
begin

    cItem := TMenuItem(Sender);

    if cItem.Tag = maxint then begin
       cPosition := FCurrentRapport.PositionRapport;

    end else
       cPosition := cItem.Tag;


    FBase2DonneesRapports.LoadRapportFromDB(cPosition, sRapport);

    txtRapportLast.Text := sRapport;

end;


procedure TfrmRapportHistorique.LoadCurrentInForm;
var cItem: TMenuItem;
    i: integer;
    cPosition: integer;
    bDejaAdd: boolean;
    //peGalaxie: PGalaxiePlanete;
begin

    gbPlanete.Caption := format(_('Informations - %s'), [mbtPlanetLocationToStr(FCurrentRapport.PlaneteLocation)]); // + ;

    if FCurrentRapport.RapportFullOri = '' then
       FBase2DonneesRapports.LoadRapportDB(FCurrentRapport);

    txtRapportLast.Text := FCurrentRapport.RapportFullOri;

    seNbSondage.Value := FCurrentRapport.NbEspionnage;
    seNbAttaque.Value := FCurrentRapport.NbAttack;



    txtInfos.Lines.Clear;
    txtInfos.Lines.Add(_('Espionnage:'));
    mrShowHistorique(FCurrentRapport.DateLastEspionnage, txtInfos.Lines);

    txtInfos.Lines.Add('');
    txtInfos.Lines.Add(_('Attaque:'));
    mrShowHistorique(FCurrentRapport.DateLastAttaque, txtInfos.Lines);

    chkTropBienDef.Checked := sfcFlagsIsIn(FLAG_TROP_BIEN_DEF, FCurrentRapport.Flags);
    chkNivEspEleve.Checked := sfcFlagsIsIn(FLAG_NIV_ESP_ELEVE, FCurrentRapport.Flags);
    chkNeJamaisAttaquer.Checked := sfcFlagsIsIn(FLAG_NE_JAMAIS_ATTACK, FCurrentRapport.Flags);
    chkPouleAuxOeufsDor.Checked := sfcFlagsIsIn(FLAG_POULE_AUX_OEUFS_DOR, FCurrentRapport.Flags);
    chkTropPeuDev.Checked := sfcFlagsIsIn(FLAG_MODE_TROP_PEUDEV, FCurrentRapport.Flags);
    chkNePasSonderPourCetteSession.Checked := sfcFlagsIsIn(FLAG_NEPAS_SONDER_TEMPORAIREMENT, FCurrentRapport.Flags);

    chkPlaneteARecycler.Checked    := sfcFlagsIsIn(FLAG_A_RECYCLER, FCurrentRapport.Flags);
    chkPlaneteDejaRecycler.Checked := sfcFlagsIsIn(FLAG_DEJA_RECYCLER, FCurrentRapport.Flags);


    // menVoirAncienRapport

    menVoirAncienRapport.Clear;





    cItem := TMenuItem.Create(menVoirAncienRapport);
    cItem.Caption := _('Le plus récent');
    cItem.OnClick := memRapportOnClick;
    cItem.Tag := maxint;
    menVoirAncienRapport.Add(cItem);
    bDejaAdd := false;

    for i := 0 to MAX_INDICE_HISTORIQUE do begin
       cPosition := FCurrentRapport.VieuxRapport[i];

       if cPosition > 0 then begin

          if bDejaAdd = false then begin
             cItem := TMenuItem.Create(menVoirAncienRapport);
             cItem.Caption := '-';
             menVoirAncienRapport.Add(cItem);

             bDejaAdd := true;
          end;

          cItem := TMenuItem.Create(menVoirAncienRapport);
          cItem.Caption := 'Position: ' + IntToStr(cPosition);
          cItem.OnClick := memRapportOnClick;
          cItem.Tag := cPosition;
          menVoirAncienRapport.Add(cItem);

       end;

    end;



    ModifStatsMenu(FCurrentRapport.PlaneteLocation);


end;

procedure TfrmRapportHistorique.ModifStatsMenu(Coord: TPlanetLocation);
var peGalaxie: PGalaxiePlanete;
begin

    FSondageAlliance := '';
    peGalaxie := FBase2DonneesPlanete.Get_Pointeur(Coord);
    if peGalaxie <> nil then begin

       if peGalaxie.Alliance = '' then begin
          menStatsAlliance.Caption := _('Stats alliance (aucune)');
          menStatsAlliance.Enabled := false;


       end else begin
          FSondageAlliance := peGalaxie.Alliance;
          menStatsAlliance.Caption := format(_('Stats alliance (%s)'), [peGalaxie.Alliance]);


          menStatsAlliance.Enabled := true;
       end;

    end else begin
       menStatsAlliance.Caption := _('Stats alliance (inconnu)');
       menStatsAlliance.Enabled := false;
    end;

    menStatsAllianceSondage.Caption := menStatsAlliance.Caption;
    menStatsAllianceSondage.Enabled := menStatsAlliance.Enabled;

end;


procedure TfrmRapportHistorique.menActionMonterClick(Sender: TObject);
begin
    if FCurrPlayerCurrPlanete = nil then exit;

    if FLastLigneSelectPlaneteScript > 1 then begin
       FCurrPlayerCurrPlanete.cActions.Exchange(FLastLigneSelectPlaneteScript - 1, FLastLigneSelectPlaneteScript - 2);

       // Met à jour l'affichage
       AfficheActionInGrid(sgElementsAction, FCurrPlayerCurrPlanete.cActions);
    end;

    
end;

procedure TfrmRapportHistorique.UpdateAll;
begin
(*
    if chkOngletTousDisable.Checked = false then
       UpdateAllSpec(sgPlanetes, FBase2DonneesRapports);
       *)

    UpdateAllSpec(sgPlanetesRecentes, FBaseRecent);
    UpdateAllSpec(sgPlanetesPoulesDor, FBaseVacheAlaid);
    UpdateAllSpec(sgFiltrer, FBaseFiltree);

    sggUpdateChampsDeRuine(sgChampDeRuines, FChampDeRuineList, FBase2DonneesRapports, FCurrentPlayer);
end;


procedure TfrmRapportHistorique.UpdateStatsAlliance(Grille: TAdvStringGrid);
var DoClear: boolean;
    CurrInfos : PPlayerStatsAllX;
    i, r : integer;
    strColonies: string;
begin


    DoClear := true;

    if (FStatsAlliance = nil) or (FStatsAlliance.Count = 0) then begin
       Grille.RemoveRows(2, Grille.RowCount - 2);

       for i := 0 to Grille.ColCount - 1 do begin
          Grille.Cells[i, 1] := '';
       end;

       if FStatsAlliance = nil then
          Grille.Cells[3, 1] := _('Aucune liste chargée')
       else
          Grille.Cells[3, 1] := _('Aucun élément');


       exit;
    end;




    if Grille.RowCount > 1 then begin
       if DoClear then begin

          // Supprime les lignes super flu
          if Grille.RowCount > FStatsAlliance.Count then begin
             Grille.RemoveRows(2, Grille.RowCount - 1 - FStatsAlliance.Count);
          end;

       end;
    end;


    r := 1;
    Grille.BeginUpdate;

    FCurrDate := DateTimeToUnix(Now);


    for i := 0 to FStatsAlliance.Count - 1 do begin
        CurrInfos := FStatsAlliance.Items[i];

        if (Grille.RowCount = r) and (r > 1) then begin
           Grille.AddRow;
           r := Grille.RowCount - 1;
        end;

        //UpdateDataStats(r, CurrInfos, Grille);
        msgUpdateStatsRow(Grille, r, CurrInfos);

        if i = 0 then begin
           AfficheMsgGalaxy('');
           AfficheMsgGalaxy('');
           AfficheMsgGalaxy('############################################');
           AfficheMsgGalaxy('############################################');
           AfficheMsgGalaxy(format(_('-> Statistiques alliance: %s'), [CurrInfos.Alliance]));

        end;

        AfficheMsgGalaxy('');
        AfficheMsgGalaxy('[b]' + CurrInfos.Nom + '[/b]');

        if CurrInfos.Total.Points > 0 then
           AfficheMsgGalaxy(format(_('Points: %s (Place: %d)'), [sfcFormatStrToMilliersP(CurrInfos.Total.Points), CurrInfos.Total.Place]))
        else
           AfficheMsgGalaxy('Points: [i](Non classé)[/i]');


        if CurrInfos.Flottes.Points > 0 then
           AfficheMsgGalaxy(format(_('Flottes: %s (Place: %d)'), [sfcFormatStrToMilliersP(CurrInfos.Flottes.Points), CurrInfos.Flottes.Place]))
        else
           AfficheMsgGalaxy('Flottes: [i](Non classé)[/i]');

        if CurrInfos.Recherche.Points > 0 then
           AfficheMsgGalaxy(format(_('Recherche: %s (Place: %d)'), [sfcFormatStrToMilliersP(CurrInfos.Recherche.Points), CurrInfos.Recherche.Place]))
        else
           AfficheMsgGalaxy('Recherche: [i](Non classé)[/i]');


        strColonies := GetPlaneteTokenForThisPlayer(CurrInfos.Nom, ' , ');
        if strColonies <> '' then begin
           AfficheMsgGalaxy(format(_('Colonies: %s'), [strColonies]));
        end;


        Inc(r);
    end;

    Grille.EndUpdate;

    
end;


procedure TfrmRapportHistorique.LoadAndUpdateSystemSolaire(System: integer);
var r: integer;
begin

    FCurrSystemSolaire.Clear;

    if FBase2DonneesPlanete.Count = 0 then begin
       // Base de données de planète non chargée
       Status(_('Base de données de planètes non chargées'));
       exit;
    end;

    r := FCurrSystemSolaire.ImportSystemSolaire(System, FBase2DonneesPlanete);

    if (r = 0) or (FCurrSystemSolaire.Count = 0) then begin
       // Base de données de planète non chargée
       Status(format(_('Système solaire %d introuvable'), [System]));

    end;

    UpdateSystemSolaire(gdSystemSolaire);


end;


    //FCurrVaisseuxList: TCollectionVaisseauSelInfos;
procedure TfrmRapportHistorique.UpdateVaisseaux(Grille: TAdvStringGrid);
var DoClear: boolean;
    CurrInfos: PVaisseauSelInfos;
    i, r: integer;
begin

    if (FCurrVaisseuxList = nil) or (FCurrVaisseuxList.Count = 0) then begin
       Grille.RemoveRows(2, Grille.RowCount - 2);

       if FCurrVaisseuxList = nil then
          Grille.Cells[0, 1] := _('Aucune planète chargée')
       else
          Grille.Cells[0, 1] := _('Aucun vaisseaux');

       exit;
    end;


    Grille.BeginUpdate;

    DoClear := true;

    if Grille.RowCount > 1 then begin
       if DoClear then begin
         // sgTMS.RemoveRows(2, sgTMS.RowCount - 2);

          // Supprime les lignes super flu
          if Grille.RowCount > FCurrVaisseuxList.Count then begin
             Grille.RemoveRows(2, Grille.RowCount - 1 - FCurrVaisseuxList.Count);
          end;

       end else
        //  j := 1;

    end else begin
     //  j := 0;
    end;


    r := 1;


    FCurrDate := DateTimeToUnix(Now);

    for i := 0 to FCurrVaisseuxList.Count - 1 do begin
        CurrInfos := FCurrVaisseuxList.Items[i];


        if (Grille.RowCount = r) and (r > 1) then begin
           Grille.AddRow;
           r := Grille.RowCount - 1;
        end;

        UpdateDataVaisseaux(r, CurrInfos, Grille);

        Inc(r);
    end;

    Grille.EndUpdate;


end;





procedure TfrmRapportHistorique.UpdateAllSpecForSocket(t: TTemplatePage; BDD: TList);
var CurrInfos: PRapportHead;
    i, r: integer;
begin


    if (BDD = nil) or (t = nil) or (BDD.Count = 0) then begin
       t.ConditionSet(TPL_COND_TAB_COUNT, 0);
       exit;
    end;


    // date globale
    FCurrDate      := DateTimeToUnix(Now);
    ttdCurrentDate := FCurrDate;

    t.ConditionSet(TPL_COND_TAB_COUNT, BDD.Count);

    for i := 0 to BDD.Count - 1 do begin
        t.BoucleStart(TPL_TAB_LOOP_RAPPORT_LIST);

        CurrInfos := BDD.Items[i];

        UpdateDataForSocket(CurrInfos^, t);

        t.BoucleEnd;
    end;


end;


procedure TfrmRapportHistorique.UpdateSondagesForSocket(t: TTemplatePage);
var DoClear: boolean;
    CurrInfos: PPlaneteASonder;
    i, r: integer;
begin


    if (FCurrentPlayer.SondagePlanetesList = nil) or (FCurrentPlayer.SondagePlanetesList.Count = 0) or (t = nil) then begin
       t.ConditionSet(TPL_COND_TAB_COUNT, 0);
       exit;
    end;


    // date globale
    FCurrDate      := DateTimeToUnix(Now);
    ttdCurrentDate := FCurrDate;

    t.ConditionSet(TPL_COND_TAB_COUNT, FCurrentPlayer.SondagePlanetesList.Count);

    for i := 0 to FCurrentPlayer.SondagePlanetesList.Count - 1 do begin
        t.BoucleStart(TPL_TAB_LOOP_SONDAGE);

        CurrInfos := FCurrentPlayer.SondagePlanetesList.Items[i];

        UpdateDataSondageForSocket(CurrInfos^, t);

        t.BoucleEnd;
    end;

end;


procedure TfrmRapportHistorique.UpdateSondages(Grille: TAdvStringGrid);
var DoClear: boolean;
    CurrInfos: PPlaneteASonder;
    i, r: integer;
    peGalaxie: PGalaxiePlanete;
    DataRapport: PRapportHead;
begin


    if (FCurrentPlayer.SondagePlanetesList = nil) or (FCurrentPlayer.SondagePlanetesList.Count = 0) then begin
       Grille.RemoveRows(2, Grille.RowCount - 2);

       for i := 0 to Grille.ColCount - 1 do begin
          Grille.Cells[i, 1] := '';
       end;

       if FCurrentPlayer.SondagePlanetesList = nil then
          Grille.Cells[3, 1] := _('Aucune liste chargée')
       else
          Grille.Cells[3, 1] := _('Aucun élément');


       exit;
    end;

    Grille.BeginUpdate;

    DoClear := true;

    if Grille.RowCount > 1 then begin
       if DoClear then begin
         // sgTMS.RemoveRows(2, sgTMS.RowCount - 2);

          // Supprime les lignes superflues
          if Grille.RowCount > FCurrentPlayer.SondagePlanetesList.Count then begin
             Grille.RemoveRows(2, Grille.RowCount - 1 - FCurrentPlayer.SondagePlanetesList.Count);
          end;

       end else
        //  j := 1;

    end else begin
     //  j := 0;
    end;

    r := 1;


    msgCurrDate := DateTimeToUnix(Now);

    for i := 0 to FCurrentPlayer.SondagePlanetesList.Count - 1 do begin
        CurrInfos := FCurrentPlayer.SondagePlanetesList.Items[i];


        if (Grille.RowCount = r) and (r > 1) then begin
           Grille.AddRow;
           r := Grille.RowCount - 1;
        end;


        peGalaxie := FBase2DonneesPlanete.Get_Pointeur(CurrInfos.Coord);
        DataRapport := FBase2DonneesRapports.Get_Pointeur(CurrInfos.Coord);

        msgUpdateDataSondageRow(Grille, r, CurrInfos, peGalaxie, DataRapport, FCurrentPlayer);


        Inc(r);
    end;

    Grille.EndUpdate;


end;

procedure TfrmRapportHistorique.UpdateSystemSolaire(Grille: TAdvStringGrid);
var DoClear: boolean;
    CurrInfos: PGalaxiePlanete;
    i, r: integer;
    peRapport: PRapportHead;
begin


    FBaseCurrSystemSolaire.Clear;

    if (FCurrSystemSolaire = nil) or (FCurrSystemSolaire.Count = 0) then begin
       Grille.RemoveRows(2, Grille.RowCount - 2);

       for i := 0 to Grille.ColCount - 1 do begin
          Grille.Cells[i, 1] := '';
       end;

       if FCurrSystemSolaire = nil then
          Grille.Cells[3, 1] := _('Aucune liste chargée')
       else
          Grille.Cells[3, 1] := _('Aucun élément');


       exit;
    end;

    Grille.BeginUpdate;

    DoClear := true;

    if Grille.RowCount > 1 then begin
       if DoClear then begin
         // sgTMS.RemoveRows(2, sgTMS.RowCount - 2);

          // Supprime les lignes super flu
          if Grille.RowCount > FCurrSystemSolaire.Count then begin
             Grille.RemoveRows(2, Grille.RowCount - 1 - FCurrSystemSolaire.Count);
          end;

       end else
        //  j := 1;

    end else begin
     //  j := 0;
    end;

    r := 1;

    msgCurrDate := DateTimeToUnix(Now);

    for i := 0 to FCurrSystemSolaire.Count - 1 do begin
        CurrInfos := FCurrSystemSolaire.Items[i];


        if (Grille.RowCount = r) and (r > 1) then begin
           Grille.AddRow;
           r := Grille.RowCount - 1;
        end;

        peRapport := FBase2DonneesRapports.Get_Pointeur(CurrInfos.Location);
        if peRapport <> nil then
           FBaseCurrSystemSolaire.Add(peRapport);


        msgUpdateDataSystemSolaireRow(Grille, r, CurrInfos, peRapport, FCurrentPlayer);


        Inc(r);
    end;

    Grille.EndUpdate;

end;





procedure TfrmRapportHistorique.UpdateAllSpec(Grille: TAdvStringGrid; BDD: TList);
var DoClear: boolean;
    CurrInfos: PRapportHead;
    i, r: integer;
    peGalaxie: PGalaxiePlanete;
begin

    DoClear := true;

    if (BDD = nil) or (BDD.Count = 0) then begin
       Grille.RemoveRows(2, Grille.RowCount - 2);

       for i := 0 to Grille.ColCount - 1 do begin
          Grille.Cells[i, 1] := '';
       end;

       if BDD = nil then
          Grille.Cells[4, 1] := _('Aucune liste chargée')
       else
          Grille.Cells[4, 1] := _('Aucun élément');


       exit;
    end;

    Grille.BeginUpdate;

    if Grille.RowCount > 1 then begin
       if DoClear then begin
         // sgTMS.RemoveRows(2, sgTMS.RowCount - 2);

          // Supprime les lignes super flu
          if Grille.RowCount > BDD.Count then begin
             r := Grille.RowCount - 1 - BDD.Count;

             if r > 800 then begin
                Grille.ClearRows(2, r);
             end else begin
                Grille.RemoveRows(2, r);
             end;

           //  Grille.RemoveRowsInternal(2, Grille.RowCount - 1 - BDD.Count);


          end;
       //   j := 0;

       end else
        //  j := 1;

    end else begin
     //  j := 0;
    end;

    r := 1;

    msgCurrDate := DateTimeToUnix(Now);

    for i := 0 to BDD.Count - 1 do begin
        CurrInfos := BDD.Items[i];


        if (Grille.RowCount = r) and (r > 1) then begin
           Grille.AddRow;
           r := Grille.RowCount - 1;
        end;

        //UpdateData(r, CurrInfos, Grille);

        peGalaxie := FBase2DonneesPlanete.Get_Pointeur(CurrInfos.PlaneteLocation);
        msgUpdateRapportRow(Grille, r, CurrInfos, peGalaxie, cbAttaquePlanete.Text, FCurrentPlayer);

        Inc(r);
    end;

    Grille.EndUpdate;

end;

function TfrmRapportHistorique.AnalyseRapportCurr: integer;
begin
    Result := AnalyseRapport(txtRapport.Text, true, false, true);
    txtRapport.Lines.Clear;
end;


function TfrmRapportHistorique.AnalyseRapport(sRapport: string; bMakeUpdateListRecent, bMakeUpdateListAll, FRapportTrieLorsDeLajout: boolean): integer;
var //x1: TRapportInfos;
    Rapport: TRapportHead;
    pe: PRapportHead;
    localBackup: TextFile;
    Delta: int64;
    r: integer;
    strx: widestring;

    bSetFlagPeuDev: boolean;
    bIsLune: boolean;
    ts : TSystemTime;

    peGalaxy: PGalaxiePlanete;
    bPlaneteNameIsLune: boolean;


    // niv de la mine de métal + mine de cristal
    MineMetalAndCristalLevel: integer;
    xLunePossibleFromName   : boolean;
    xLuneObligeFromBatiment : boolean;
    xBatimentsNbType        : integer;
begin
    FRapportLastAdd := nil;
    Result := -1;

    if FCurrentPlayer = nil then begin
       exit;
    end;

    if FileExists(FFileBackupRapport) = false then begin
       CreateFile(FFileBackupRapport, ts);
    end;



       AssignFile(localBackup, FFileBackupRapport);

       {$I-}
       Append(localBackup);
       {$I+}

       // IOResult renvoie 0 = cela signifie que la dernière opération d'E/S a réussi
       if NoT(IOResult = 0) then begin
          // echec
          Status(_('Impossible de faire un backup du rapport'));

       end else begin
          WriteLn(localBackup, '');
          WriteLn(localBackup, '');
          WriteLn(localBackup, 'DateAjout=' + IntToStr(DateTimeToUnix(Now)));
          WriteLn(localBackup, txtRapport.Text);

          CloseFile(localBackup);
       end;







    //
    // Début du verrouillage
    //

    FCurrentPlayer.Lock;


    //x1 := TRapportInfos.Create(FGidToStr);
    //x1.UnitsInfos := FUnitesInformations;

    Rapport := FCurrentPlayer.AnalyseRapportEsp(txtRapport.Lines.Text);

    if (Rapport.PlaneteLocation.Galaxie < 1) then begin
       // Rapport invalide
       FCurrentPlayer.Unlock;
       Status(_('Rapport invalide (2)'));
       exit;
    end;


    MineMetalAndCristalLevel := FCurrentPlayer.LastRapportAnalyse.MineMetalLevel + FCurrentPlayer.LastRapportAnalyse.MineCristalLevel;
    xLunePossibleFromName    := FCurrentPlayer.LastRapportAnalyse.LunePossibleFromName;
    xLuneObligeFromBatiment  := FCurrentPlayer.LastRapportAnalyse.LuneObligeFromBatiment;
    xBatimentsNbType         := FCurrentPlayer.LastRapportAnalyse.BatimentsNbType;

    FCurrentPlayer.Unlock;

    //
    // Fin du verrouillage
    //



    // Verifie si la galaxie correspond
    if (Rapport.PlaneteLocation.Galaxie <> FBase2DonneesRapports.Galaxie) then begin
       // la base de donnees chargees est une galaxie differente de celle charge
       // verifie si une base de donnees a ete charge au moins
       if FBase2DonneesRapports.Galaxie < 1 then begin
          // aucune base de donnees a ete charge
          // verifie si un profil a ete charge
          if FCurrentPlayer.Conf.IsValidProfil then begin
             // profil valide
             Application.BringToFront;
             
             //r := Application.MessageBox(PChar(), PChar(), MB_OK + MB_ICONERROR);
             if FNoMessageBoxErrorForRapportEspLecture = false then begin
                r := MessageBoxW(Handle, PWideChar(_('Aucune base de données de chargée. Rapport non ajouté.')), PWideChar(_('Erreur')), MB_OK + MB_ICONERROR);

             end;



             Status(_('Profil valide, mais aucune base de données de chargée. Rapport non ajouté: ') + mbtPlanetLocationToStr(Rapport.PlaneteLocation));
             Result := CNT_ERRROR_DB_INVALID;
             exit;

          end else begin
             // aucun profil de charger
             Application.BringToFront;

             //r := Application.MessageBox(PChar(_('Aucun profil de chargée. Rapport non ajouté.')), PChar(_('Erreur')), MB_OK + MB_ICONERROR);
             if FNoMessageBoxErrorForRapportEspLecture = false then begin
                r := MessageBoxW(Handle, PWideChar(_('Aucun profil de chargée. Rapport non ajouté.')), PWideChar(_('Erreur')), MB_OK + MB_ICONERROR);

             end;


             Status(_('Profil invalide (et aucune base de données de chargée). Rapport non ajouté: ') + mbtPlanetLocationToStr(Rapport.PlaneteLocation));
             Result := CNT_ERRROR_DB_INVALID;
             exit;
          end;


       end else begin
          // base de donnees valide, mais ne correspond pas a la galaxie
          Application.BringToFront;
          strx := format(_('La base de donnees actuelle (Galaxie %d) ne correspond pas a celle du rapport (Galaxie %d). La rapport n''a pas été ajouté.'), [FBase2DonneesRapports.Galaxie, Rapport.PlaneteLocation.Galaxie]);
          //r := Application.MessageBox(PChar(strx), PChar(_('Erreur')), MB_OK + MB_ICONERROR);

          if FNoMessageBoxErrorForRapportEspLecture = false then begin
             r := MessageBoxW(Handle, PWideChar(strx), PWideChar(_('Erreur')), MB_OK + MB_ICONERROR);

          end;


          Status(strx + ' ' + mbtPlanetLocationToStr(Rapport.PlaneteLocation));
          Result := CNT_ERRROR_DB_INVALID;
          exit;
       end;

    end;





    ////////////////////////
    // Flag trop peu dev
    ///////////////////////
    bSetFlagPeuDev := false;
    if FCurrentPlayer.Conf.NewbzSetFlagPeuDevAuto > 0 then begin
       if scBatiments in Rapport.SectionConnu then begin

          if MineMetalAndCristalLevel < FCurrentPlayer.Conf.NewbzLevelMineBoth then begin
             bSetFlagPeuDev := true;
          end;

       end;
    end;



    ////////////////////////
    // Vérification lune
    ///////////////////////
    bIsLune := false;
    
    if xLunePossibleFromName then begin

       if MineMetalAndCristalLevel > 0 then begin
          // ce n'est pas une lune
          Status(_('Rapport: Planète avec un nom de lune (ajouté en tant que planète) - ') + mbtPlanetLocationToStr(Rapport.PlaneteLocation));

       end else begin

          peGalaxy := FBase2DonneesPlanete.Get_Pointeur(Rapport.PlaneteLocation);

          if peGalaxy = nil then begin


             if xLuneObligeFromBatiment then begin
                Status(_('Rapport: Rapport de lune non cartographiée (ajouté en tant que lune) - ') + mbtPlanetLocationToStr(Rapport.PlaneteLocation));
                bIsLune := true;

             end else begin
                if scBatiments in Rapport.SectionConnu then begin
                   // pas de base lunaire et la section batiment est connu
                   Status(_('Rapport: Rapport de lune non cartographiée (ajouté en tant que planète) (de plus pas de base lunaire trouvé dans les batiments) - ') + mbtPlanetLocationToStr(Rapport.PlaneteLocation));


                end else begin
                   Status(_('Rapport: Rapport de lune non cartographiée (ajouté en tant que planète) (la section batiment est introuvable, impossible de vérifier la présence de la base lunaire) - ') + mbtPlanetLocationToStr(Rapport.PlaneteLocation));
                end;
             end;


          end else begin


             bPlaneteNameIsLune := SameText(peGalaxy.NomPlanete, LangParsing.GetData('rapport_st_lune', 'Lune'));

             if peGalaxy.Lune.Surface > 0 then begin
                // Il y a bien une lune à cet emplacement
                if xLuneObligeFromBatiment then begin
                   // c'est obligé que ce soit une lune d'après les batiments
                   bIsLune := true;

                end else begin
                   // pas de base lunaire

                   if scBatiments in Rapport.SectionConnu then begin
                      // la section batiment est connu
                      // lune récente peut-être, mais bon...
                      // il ne faut pas oublier que l'on a toujours x1.MineMetalLevel + x1.MineCristalLevel = 0 de
                      // vérifié

                      if (xBatimentsNbType < 3) and NoT(bPlaneteNameIsLune) then begin
                         // il y a surement qu'une usine de robot si c'est un noob...
                         bIsLune := true;

                      end else begin
                         Status(_('Rapport: Pas de base lunaire trouvé (la lune est peut-être récente) (ajouté en tant que planète) - ') + mbtPlanetLocationToStr(Rapport.PlaneteLocation));

                      end;



                   end else begin
                      // pas de base lunaire et la section batiment n'est pas connu
                      if bPlaneteNameIsLune then begin
                         // la planète s'appelle Lune
                         Status(_('Rapport: Le nom de la planète correspond à Lune (ajouté comme planète) - ') + mbtPlanetLocationToStr(Rapport.PlaneteLocation));

                      end else begin
                         Status(_('Rapport: Section batiment introuvable (ajouté comme Lune) - ') + mbtPlanetLocationToStr(Rapport.PlaneteLocation));
                         bIsLune := true;
                      end;

                   end;

                end;




             end else begin
                //////////////////////////////////////////
                // il n'y a pas de lune à cet emplacement
                if xLuneObligeFromBatiment then begin
                   Status(_('Rapport: Pas de lune à l''emplacement mais base lunaire trouvé (ajouté en tant que lune, mais recartographier quand même le système solaire - ') + mbtPlanetLocationToStr(Rapport.PlaneteLocation));
                   bIsLune := true;

                end else begin

                   if scBatiments in Rapport.SectionConnu then begin
                      // la section batiment est connu
                      // lune récente peut-être, mais bon...
                      Status(_('Rapport: Pas de lune à l''emplacement, ni de base lunaire (ajouté en tant que planète) - ') + mbtPlanetLocationToStr(Rapport.PlaneteLocation));

                   end else begin
                      // pas de base lunaire et la section batiment n'est pas connu
                      Status(_('Rapport: Pas de lune à l''emplacement, section batiment non connu (ajouté en tant que planète) - ') + mbtPlanetLocationToStr(Rapport.PlaneteLocation));

                   end;

                end;

             end;

          end;

       
          if bIsLune then begin
             Rapport.PlaneteLocation.Position := Rapport.PlaneteLocation.Position + CNT_POSITION_LUNE;

             // une lune a obligatoirement le flag trop peu dev d'activé
             bSetFlagPeuDev := false;
          end;
       end;
    end;


    // Maintenant, et seulement maintenant que l'on sait si c'est une lune ou pas
    // (et donc que l'on connait la valeur réelle de position)
    // on extrait le pointeur
    pe := FBase2DonneesRapports.Get_Pointeur(Rapport.PlaneteLocation);


    if NoT(scDefense in Rapport.SectionConnu) or NoT(scFlotte in Rapport.SectionConnu) then begin
       // Ajoute tout seul le flag de niveau d'espionnage élevé
       sfcFlagsAdd(FLAG_NIV_ESP_ELEVE, Rapport.Flags);
    end;

    if bSetFlagPeuDev then
       sfcFlagsAdd(FLAG_MODE_TROP_PEUDEV, Rapport.Flags);


    if pe = nil then begin
       // le rapport n'existe pas
       FRapportLastAdd := FBase2DonneesRapports.Add(Rapport);
       FBase2DonneesRapports.Trie;

       // ici on n'ajoute que le pointeur
       FBaseRecent.Add(FRapportLastAdd);

       if FRapportTrieLorsDeLajout then
          FBaseRecent.TrieParGT;


       if bMakeUpdateListAll then begin
          UpdateAll;

       end else if bMakeUpdateListRecent then begin
          UpdateAllSpec(sgPlanetesRecentes, FBaseRecent);
       end;

       // sgPlanetes.InsertRows(1, 1);
       
    end else begin
       // le rapport existe déjà
       FRapportLastAdd := pe;

       if FBaseRecent.IndexOf(FRapportLastAdd) < 0 then begin
          // ici on n'ajoute que le pointeur
          FBaseRecent.Add(FRapportLastAdd);

          if FRapportTrieLorsDeLajout then
             FBaseRecent.TrieParGT;

          if bMakeUpdateListRecent then
             UpdateAllSpec(sgPlanetesRecentes, FBaseRecent);
       end;




       // Vérifie si les rapports ne sont pas identique
       if (pe.RapportFullOri = Rapport.RapportFullOri) then begin
          // Rapport égaux
          // Cependant, lors du chargement de la base de données, pe.RapportFullOri
          // sera vide
          txtDebug1.Lines.Add(_('Rapport égaux'));
          Result := 2;
          exit;

       end;

       pe.Ressource := Rapport.Ressource;
       pe.NbDefense := Rapport.NbDefense;
       pe.NbFlotte  := Rapport.NbFlotte;
       pe.PourcentContreEspion := Rapport.PourcentContreEspion;

       pe.RecyclageNbRessource := Rapport.RecyclageNbRessource;
       pe.DefenseScore         := Rapport.DefenseScore;


       if mrInjectOnlyIfNeed(pe.DateLastEspionnage, Rapport.DateLastEspionnage[0]) then begin
          Inc(pe.NbEspionnage);

       end;

       pe.SectionConnu := Rapport.SectionConnu;

       if NoT(scDefense in Rapport.SectionConnu) or NoT(scFlotte in Rapport.SectionConnu) then begin
          // Ajoute tout seul le flag de niveau d'espionnage élevé
          sfcFlagsAdd(FLAG_NIV_ESP_ELEVE, pe.Flags);
       end;

       if bSetFlagPeuDev then
          sfcFlagsAdd(FLAG_MODE_TROP_PEUDEV, pe.Flags)
       else begin
          // sinon l'enlève
          sfcFlagsDel(FLAG_MODE_TROP_PEUDEV, pe.Flags);
       end;

       pe.bShouldBeUpdateFixed := true;
       pe.bShouldBeUpdateRapport := true;
       pe.RapportFullOri := Rapport.RapportFullOri;


       RefreshRapportLignes(pe);
    end;


    FBase2DonneesRapports.SaveToFile('');


    txtRapport.Lines.Clear;
    Result := 1;

end;

procedure TfrmRapportHistorique.cmdAnalyserClick(Sender: TObject);
begin
    //AnalyseRapportCurr;
end;

procedure TfrmRapportHistorique.cmdAnnulerTransportMassifClick(Sender: TObject);
begin
   FCurrentPlayer.ProcRecolteArret := true;
end;

procedure TfrmRapportHistorique.UpdateDataVaisseaux(Row: integer; Data: PVaisseauSelInfos; Grille: TAdvStringGrid);
var i: integer;
    LigneBackColor: TColor;
    LigneFontColor: TColor;
begin

    LigneFontColor := clBlack;
    LigneBackColor := clWhite;



    Grille.Cells[0, Row] := Data.GIDNom;
    Grille.CellProperties[0, Row].Alignment := Classes.taRightJustify;
    Grille.CellProperties[0, Row].BrushColor := LigneBackColor;
    Grille.CellProperties[0, Row].FontColor  := LigneFontColor;



    i := 1;
    Grille.Cells[i, Row] := IntToStr(Data.QuantiteVoulu);
    Grille.CellProperties[i, Row].Alignment  := Classes.taLeftJustify;
    Grille.CellProperties[i, Row].BrushColor := LigneBackColor;
    Grille.CellProperties[i, Row].FontColor  := LigneFontColor;
    Inc(i);


    // Quantité de vaisseaux
    Grille.Cells[i, Row] :=  IntToStr(Data.Max);
    Grille.CellProperties[i, Row].Alignment  := Classes.taLeftJustify;
    Grille.CellProperties[i, Row].BrushColor := LigneBackColor;
    Grille.CellProperties[i, Row].FontColor  := LigneFontColor;
    Inc(i);



end;


procedure TfrmRapportHistorique.UpdateDataSondageForSocket(Data: TPlaneteASonder; t: TTemplatePage);
var i: integer;
    iDiff, LastDate: int64;

    peStats: PPlayerStats;
    peGalaxie: PGalaxiePlanete;
    bIsPlaneteVide, bIsAllianceAlliees: boolean;

    DataRapport: PRapportHead;
    PourcentGT: single;
begin


    bIsPlaneteVide := false;
    bIsAllianceAlliees := false;

    peGalaxie := FBase2DonneesPlanete.Get_Pointeur(Data.Coord);
    DataRapport := FBase2DonneesRapports.Get_Pointeur(Data.Coord);

    // Galaxie et Stats
    ttdSetGalaxyAndStats(peGalaxie, t, FCurrentPlayer);

    // Rapport
    ttdSetRapport(DataRapport, t);


    t.BoucleSetVar(TPL_TAB_VARLOOP_COORD  , mbtPlanetLocationToStr(Data.Coord));
    t.BoucleSetCond(TPL_TAB_CONDLOOP_COORD, mbtIsLune(Data.Coord));



    t.BoucleSetCond(TPL_TAB_CONDLOOP_NB_SONDES    , Data.NbSondes);


    // Date du sondage
    if Data.DateSondage < 100 then begin
       t.ConditionSet(TPL_TAB_CONDLOOP_A_ETE_SONDE     , 0);
       t.BoucleSetVar(TPL_TAB_VARLOOP_DATE_SONDAGE_UNIX, 0);
       t.BoucleSetVar(TPL_TAB_VARLOOP_DATE_SONDAGE_DURATION, 0);
       t.BoucleSetVar(TPL_TAB_VARLOOP_DATE_SONDAGE_DURATION_STR, '');

       
    end else begin
       t.ConditionSet(TPL_TAB_CONDLOOP_A_ETE_SONDE, 1);

       t.BoucleSetVar(TPL_TAB_VARLOOP_DATE_SONDAGE_UNIX, Data.DateSondage);

       iDiff := FCurrDate - Data.DateSondage;

       if iDiff < 2 then begin
          t.BoucleSetVar(TPL_TAB_VARLOOP_DATE_SONDAGE_DURATION, 1);
          t.BoucleSetVar(TPL_TAB_VARLOOP_DATE_SONDAGE_DURATION_STR,  _('1 sec.'));
       end else begin
          t.BoucleSetVar(TPL_TAB_VARLOOP_DATE_SONDAGE_DURATION, iDiff);
          t.BoucleSetVar(TPL_TAB_VARLOOP_DATE_SONDAGE_DURATION_STR, ESBDGetDureeStrings(iDiff, false, 3));
       end;

    end;

end;




procedure TfrmRapportHistorique.Services_Commande_EnvoiRowToSocket(Data: TRapportHead; Socket: TBotServicesClient);
begin

end;



procedure TfrmRapportHistorique.UpdateDataActionScript(Row: integer; Data: PElementActionItem; Grille: TAdvStringGrid);
var i: integer;
    couleur: TColor;
begin


    // La ligne existe obligatoirement
    if Data.GID >= ACTION_GIDMISC_BEST_RESSOURCE_ACTIVITY_NEXTELEMENT then begin
       Grille.CellProperties[0, Row].FontColor := clTeal;
       Grille.CellProperties[1, Row].FontColor := clTeal;
       Grille.CellProperties[2, Row].FontColor := clTeal;
       Grille.CellProperties[3, Row].FontColor := clTeal;

    end else begin
       Grille.CellProperties[0, Row].FontColor := clBlack;
       Grille.CellProperties[1, Row].FontColor := clBlack;
       Grille.CellProperties[2, Row].FontColor := clBlack;
       Grille.CellProperties[3, Row].FontColor := clBlack;
    end;

    // Pour le fond maintenant
    Couleur := msgGetColorFromGID(Data.GID);

    for i := 0 to 7 do begin
       Grille.CellProperties[i, Row].BrushColor := couleur;
    end;

    Grille.Cells[0, Row] := FGidToStr.GetGIDStr(Data.GID);
    Grille.CellProperties[0, Row].Alignment := Classes.taRightJustify;

    Grille.Cells[1, Row] := mamGetStatusToStrShort(Data.Status);

    Grille.Cells[2, Row] := IntToStr(Data.Quantite);
    Grille.Cells[3, Row] := IntToStr(Data.NiveauRequis);


   // sgAction.Cells[4, r] := IntToStr(Element.NiveauAtteint);

end;

procedure TfrmRapportHistorique.UpdateDataForSocket(Data: TRapportHead; t: TTemplatePage);
var peGalaxie: PGalaxiePlanete;
    pDepart: TPlanetLocation;
begin


    peGalaxie := FBase2DonneesPlanete.Get_Pointeur(Data.PlaneteLocation);

    // Galaxie et Statistiques
    ttdSetGalaxyAndStats(peGalaxie, t, FCurrentPlayer);


    // Le rapport
    ttdSetRapport(@Data, t);


    // Global
    t.BoucleSetVar(TPL_TAB_VARLOOP_COORD  , mbtPlanetLocationToStr(Data.PlaneteLocation));
    t.BoucleSetCond(TPL_TAB_CONDLOOP_COORD, mbtIsLune(Data.PlaneteLocation));



(*


    // Distance de la planète attaquante
    // FDistanceColor

    if trim(cbAttaquePlanete.Text) <> '' then begin
       pDepart := SpiderGalaxieTextPlaneteToLocation(cbAttaquePlanete.Text);
       Grille.CellProperties[i, Row].FontColor  := clBlack;

       j := Abs(pDepart.SystemSolaire - Data.PlaneteLocation.SystemSolaire);
       if j < 0 then
          j := 0;
       if j > 100 then
          j := 100;

       Grille.CellProperties[i, Row].BrushColor := FDistanceColor[j];
       Grille.Cells[i, Row] := IntToStr(j);
       Grille.CellProperties[i, Row].Alignment := taCenter;

    end else begin
       Grille.CellProperties[i, Row].BrushColor := LigneBackColor;
       Grille.CellProperties[i, Row].FontColor  := LigneFontColor;
    end;
    Inc(i);

    *)

end;


procedure TfrmRapportHistorique.InitGrille(Grille: TAdvStringGrid);
var i: integer;
    PTVersion: boolean;
begin
    PTVersion := (FCurrentPlayer <> nil) and (FCurrentPlayer.Conf <> nil) and FCurrentPlayer.Conf.VersionPT;

    migInitGrilleRapportEsp(Grille, PTVersion, chkDesactiveColonneDef.Checked);
end;


procedure TfrmRapportHistorique.RefreshProfilList;
var i: integer;
    c: longword;
    TokenFiles, CurrFile, FullPath: string;
begin


   if FTunnelProfilList = nil then begin
      FTunnelProfilList := TStringList.Create;
   end else begin
      FTunnelProfilList.Clear;
   end;

   if DirectoryExists(Global_DossierProfils) = false then begin
      // il existe deja normalement
      exit;
   end;

   TokenFiles := sfcFileEnumFichiersDir(Global_DossierProfils, '*.ini', '%s', '|', c);

   if c = 0 then exit;

   for i := 1 to c do begin
      CurrFile := sfcTokenGet(TokenFiles, i, '|');
      FullPath := Global_DossierProfils + CurrFile;

      if FileExists(FullPath) then begin
         FTunnelProfilList.Add(CurrFile);

      end;

   end;


end;


procedure TfrmRapportHistorique.CreateFile(Fichier: string; tDate: TSystemTime);
var F: TextFile;
begin


    if FileExists(Fichier) = false then begin
       // le cree
       AssignFile(F, Fichier);

       {$I-}
          ReWrite(F);
       {$I+}

       // IOResult renvoie 0 => cela signifie que la dernière opération d'E/S a réussi
       if NoT(IOResult = 0) then begin
          // Erreur de creation du fichier
          {$IFDEF DEBUG}
              Status(format(_('Erreur de creation du fichier: %s'), [Fichier]));
          {$ENDIF}
       end else begin

          WriteLn(F, 'Creation - ' + IntToStr(tDate.wDayOfWeek));
          WriteLn(F, '');

          CloseFile(F);
       end;

    end;


end;

procedure TfrmRapportHistorique.FormCreate(Sender: TObject);
label lShowProfilSelection, lWizardLicenceEchec, lWizardLicenceStart;
var AppPath: string;
    i, j: integer;
    LastProfilLoaded, sTempFile: string;
    LastGalaxieLoaded: integer;
    xVarBool: boolean;
    DateEtHeure : TSystemTime;
    dtDateEtHeure: TDateTime;

    localExpire: boolean;

    iTmp: integer;
    xwStats          : TCollectionPlayerStats;


{$IFDEF AUTH_FILE_USE}
    StreamKey: TFileStream;
{$ENDIF}
begin
    FFileStatusLogEnable := false;

    FTunnelProfilList := nil;

    FNbGTForCurrentRapport := 0;
    FNbPTForCurrentRapport := 0;
    FCurrVaisseuxList := nil;
    //FCurrentProfil := nil;
    //FRapportTrieLorsDeLajout := true;
    FCurrentIndiceListAttackSel := -1;

    FNoMessageBoxErrorForRapportEspLecture := false;

    FExisteTrayIcon := false;
    bExpSimple := false;


    FForumGetDelayedAccessDone   := false;
    
    FForumGetAccessDeniedForHash := 89;

    FDoForumGetAccessInThis := false;

    FForumGetAccessNbEchec  := 0;

    FLastLigneSelectedInConstruction := -1;
    menSpiderLogin.Enabled  := false;

    FInTimerSondage    := false;

    tabBaseDeDonnees.TabVisible    := false;

    
    tabEcrireAuteur.TabVisible     := false;
    tabEcrireAuteurConfig.TabVisible := false;
    //tabIRC.TabVisible              := false;
    

 //   tabColoration.TabVisible := false;
  //  tabConstruction.TabVisible := false;


    FForumRelay.URL := '';
    FForumRelay.URLForModif := '';
    FForumRelay.DataForLogin := '';

    timAttackNotificationAndOnTimer.Interval := 0;


    FCurrentSound.Stream := nil;

    FFormCdRMonitorList := TList.Create;

    tabProfilsEdit.Enabled := false;

  //  tabWebService.TabVisible := false;

    FTunnelSessionId := TCollectionTunnelSessionId.Create;

    // Create critical section object:
    InitializeCriticalSection(ReadWriteCS);

    
    AppPath := ExtractFileDir(Application.ExeName);
    AppPath := IncludeTrailingPathDelimiter(AppPath);

    FGidToStr := TCollectionGIDtoSTR.Create;


    //FSondesAttaqueList := TCollectionAttSondeCible.Create;

    FRemplaceStrForPageWeb := TSimpleRemplaceStr.Create;


    FUnitesInformations := TCollectionUnitInfos.Create;
    FUnitesInformations.FichierSave := AppPath + 'units.ini';
    FUnitesInformations.LoadFromFile('');

    //global_sockIRC := TIRCAdv.Create(Self);


    localExpire := false;

    {$IFDEF DEBUG}
         Status(format(_('FormCreate - Unités chargés = %d'), [FUnitesInformations.Count]));
    {$ENDIF}

    Randomize;

    
    InitGrille(sgPlanetesRecentes);
    InitGrille(sgPlanetesPoulesDor);
    InitGrille(sgFiltrer);


    migInitGrilleSystemStyle(gdSystemSolaire);
    migInitGrilleSondage(sgSondages);
    migInitStatsGrille(gdStats);
    migInitStatsGrille(gdStats2);

    migInitChampDeRuineGrille(sgChampDeRuines);
   

    migInitGrilleVaisseaux(sgVaisseaux);
    migInitGrilleFlotteList(sgGridFlotteList);
    //InitGrilleMsgList(sgGridMsgList);


    migInitRessourcesView(sgRessourcesProd);
    migInitElementsConstruction(sgElementsConstructible);
    migInitActionScriptView(sgElementsAction);


    migInitListeAttaque(sgListeAttaque);

    {$IFNDEF SONDEOK}
       // Attaques aux sondes desactivee
       TabSheet3.TabVisible := false;
    //   TabSheet9.TabVisible := false;
    {$ENDIF}


    FBaseRecent            := TCollectionRapportRecent.Create;
    FBase2DonneesRapports  := TCollectionRapportHead.Create;
    FBaseVacheAlaid        := TCollectionRapportRecent.Create;
    FBaseCurrSystemSolaire := TCollectionRapportRecent.Create;
    FBaseFiltree           := TCollectionRapportRecent.Create;


    FDossierApp := IncludeTrailingPathDelimiter(ExtractFileDir(Application.ExeName));

    Global_DossierProfils := FDossierApp + 'profils\';
    FDossierGalaxieDB := FDossierApp + 'galaxie\';
    FDossierStats     := FDossierApp + 'stats\';
    Global_DossierLang      := FDossierApp + 'lang\';
    FDossierHtml      := FDossierApp + 'html\';
    FDossierTunnel    := FDossierApp + 'html\tunnel\';
    ForceDirectories(FDossierStats);



    ForceDirectories(Global_DossierProfils + 'logs\');
    AssignFile(FFileStatusLog, sfcFileGetNextNonExist(Global_DossierProfils + 'logs\status.txt', 4));

    {$I-}
    ReWrite(FFileStatusLog);
    {$I+}

    FFileStatusLogEnable := true;



{$IFDEF AUTH_FILE_USE}
    FAuthCaption := '';
    FAuthAProposDone := false;
{$ENDIF}

    
    FForumCookies := TCollectionCookieInfos.Create;


    Status(format(_('Version: %s'), [CNT_CURR_VERSION]));

    FLocalSetting := TLocalSetting.Create;
    Global_LocalSetting := FLocalSetting;

    if FLocalSetting.LoadFromFile(FDossierApp + 'settings.yk', lsoEnteteValues) = false then begin

       if FLocalSetting.Corrupted then begin
          {$IFDEF DEBUG}
               Status(_('FormCreate - LocalSetting echec (corrompu)'));
          {$ENDIF}

       end else begin
          {$IFDEF DEBUG}
               Status(_('FormCreate - LocalSetting echec (inexistant peut-être)'));
          {$ENDIF}

       end;
       
    end else begin
       // charge le fichier ini non sensible maintenant ?
       if FLocalSetting.LoadFromFile('', lsoIniData) = false then begin
          {$IFDEF DEBUG}
               Status(_('FormCreate - LocalSetting echec (corrompu)'));
          {$ENDIF}
       end;

    end;


    ///////////////////////////////////////////
    // Le chargement des données additionnelles se fait dans timAdditionnalTimer
    ///////////////////////////////////////////

    iTmp := FLocalSetting.ConfGet(CNT_LOCALSETTING_TunnelPort);
    if iTmp  < 80 then begin
       Randomize;
       iTmp := 30000 + Random(30000);

       FLocalSetting.ConfSet(CNT_LOCALSETTING_TunnelPort, iTmp);
    end;

    seTunnelPort.Value := iTmp;




    // txtIRCNick



    FNewsData := TNewsCollection.Create;
    if FNewsData.LoadFromFile(FDossierApp + 'news3.yk') = false then begin
       txtNewsAffichage.Lines.Add('Impossible d''ouvrir la base de données des News');
       txtNewsAffichage.Lines.Add('Elle est probablement déjà utilisée par une autre instance du programme (ou par une autre version du robot qui est en cours d''exécution)');
       txtNewsAffichage.Lines.Add('Si ce n''est pas le cas, effacer tous vos fichiers "news.yk"');
    end;

    // dans tous les cas on appelle cette fonction pour afficher un message
    // d'erreur si le stream est invalide
    News_PlaceOnLastest;




    FDossierDB := FDossierApp + 'db\';


    ForceDirectories(FDossierGalaxieDB);


    GetSystemTime(DateEtHeure);


    FCurrSystemSolaire := TListGalaxiePlaneteSP.Create;


    //FLanguageList := TScanLanguage.Create;




    ForceDirectories(FDossierDB);
    FDynTimer := nil;
    ForceDirectories(Global_DossierProfils);


    //RefreshProfilList;


    RefreshDbList;


  //  cmdClipboardSwitchClick(Sender);
    CaptureClipboardDesactivation;

    FStatsGetFileRecent := TScanStatsRecent.Create;

    FCurrentPlayer := TPlayerFinal.Create;
    FCurrentPlayer.DontDLAppercuPageOnChangePlanet := true;


    FScanDB := nil;


    //GetSetting(REG_PROG_NAME, REG_PROG_SECTION_CFG, REG_KEY_LASTPROFILLOADED, LastProfilLoaded);
    //GetSetting(REG_PROG_NAME, REG_PROG_SECTION_CFG, REG_LASTGALAXIELOADED, LastGalaxieLoaded);



    Randomize;


{$IFDEF AUTH_FILE_USE}
    // Verifie si le fichier existe, sinon on fait expirer le programme
    if (FileExists(AppPath + CNT_FILE_INFOS_LICENCE) = false) then begin
       bExpSimple := true;
    end;
{$ENDIF}



   // xVarBool := chkLoadAutoProfil.Checked;
   // GetSetting(REG_PROG_NAME, REG_PROG_SECTION_CFG, REG_KEY_LOADPROFIL_AT_STARTUP, xVarBool);
   // chkLoadAutoProfil.Checked := FLocalSetting.ConfLoadTheLastestProfilAtStarup <> 0;


    bDoExpiration := -9;
    pcUniversRapports.OnEnter := OnObjectEnter;


    //xVarBool := chkLoadAutoGalaxieDB.Checked;
    //GetSetting(REG_PROG_NAME, REG_PROG_SECTION_CFG, REG_KEY_LOADGALAXIE_AUTO, xVarBool);
    chkLoadAutoGalaxieDB.Checked := FLocalSetting.ConfLoadTheLastestBDOnProfilLoad <> 0;

    {$IFDEF DEBUG}
        Status(_('Dossier des profils: ') + Global_DossierProfils);
        Status(_('Dossier base de donnees: ') + FDossierDB);
        Status(_('Dernier profil charge: ') + LastProfilLoaded);
    {$ENDIF}





    // une fois chargé, la procédure SetWebPagesSaving est appellé à la fin du Create
    //xVarBool := chkDebogageWebPage.Checked;
    //GetSetting(REG_PROG_NAME, REG_PROG_SECTION_CFG, REG_KEY_SAVE_WEB_PAGES, xVarBool);
    chkDebogageWebPageOnError.Checked := FLocalSetting.ConfSaveWebPage <> 0;





    FCurrDate := DateTimeToUnix(Now);

    Inc(bDoExpiration);


    menFlagTropBienDefIncl.Tag     := FLAG_TROP_BIEN_DEF;
    menFlagTropBienDefIncl.OnClick := menFlagXXXInclClick;
    menFlagTropBienDefExcl.Tag     := menFlagTropBienDefIncl.Tag;
    menFlagTropBienDefExcl.OnClick := menFlagYYYExclClick;
    menFlagTropBienDefIgnr.Tag     := menFlagTropBienDefIncl.Tag;
    menFlagTropBienDefIgnr.OnClick := menFlagZZZIgnoreClick;


    menFlagNivEspEleveIncl.Tag     := FLAG_NIV_ESP_ELEVE;
    menFlagNivEspEleveIncl.OnClick := menFlagXXXInclClick;
    menFlagNivEspEleveExcl.Tag     := menFlagNivEspEleveIncl.Tag;
    menFlagNivEspEleveExcl.OnClick := menFlagYYYExclClick;
    menFlagNivEspEleveIgnr.Tag     := menFlagNivEspEleveIncl.Tag;
    menFlagNivEspEleveIgnr.OnClick := menFlagZZZIgnoreClick;


    menFlagNeJamaisAttackIncl.Tag     := FLAG_NE_JAMAIS_ATTACK;
    menFlagNeJamaisAttackIncl.OnClick := menFlagXXXInclClick;
    menFlagNeJamaisAttackExcl.Tag     := menFlagNeJamaisAttackIncl.Tag;
    menFlagNeJamaisAttackExcl.OnClick := menFlagYYYExclClick;
    menFlagNeJamaisAttackIgnr.Tag     := menFlagNeJamaisAttackIncl.Tag;
    menFlagNeJamaisAttackIgnr.OnClick := menFlagZZZIgnoreClick;


    menFlagPouleDorIncl.Tag     := FLAG_POULE_AUX_OEUFS_DOR;
    menFlagPouleDorIncl.OnClick := menFlagXXXInclClick;
    menFlagPouleDorExcl.Tag     := menFlagPouleDorIncl.Tag;
    menFlagPouleDorExcl.OnClick := menFlagYYYExclClick;
    menFlagPouleDorIgnr.Tag     := menFlagPouleDorIncl.Tag;
    menFlagPouleDorIgnr.OnClick := menFlagZZZIgnoreClick;


    menFlagTropPeuDevIncl.Tag     := FLAG_MODE_TROP_PEUDEV;
    menFlagTropPeuDevIncl.OnClick := menFlagXXXInclClick;
    menFlagTropPeuDevExcl.Tag     := menFlagTropPeuDevIncl.Tag;
    menFlagTropPeuDevExcl.OnClick := menFlagYYYExclClick;
    menFlagTropPeuDevIgnr.Tag     := menFlagTropPeuDevIncl.Tag;
    menFlagTropPeuDevIgnr.OnClick := menFlagZZZIgnoreClick;


    

    menFlagInactifIncl.Tag     := CNT_GALAXIE_FLAGS_INACTIF_2SEMAINES or CNT_GALAXIE_FLAGS_INACTIF_4SEMAINES;
    menFlagInactifIncl.OnClick := menFlagGalaxieXXXInclClick;
    menFlagInactifExcl.Tag     := menFlagInactifIncl.Tag;
    menFlagInactifExcl.OnClick := menFlagGalaxieYYYExclClick;
    menFlagInactifIgnr.Tag     := menFlagInactifIncl.Tag;
    menFlagInactifIgnr.OnClick := menFlagGalaxieZZZIgnoreClick;


    menFlagVacancesIncl.Tag     := CNT_GALAXIE_FLAGS_MODE_VACANCES;
    menFlagVacancesIncl.OnClick := menFlagGalaxieXXXInclClick;
    menFlagVacancesExcl.Tag     := menFlagVacancesIncl.Tag;
    menFlagVacancesExcl.OnClick := menFlagGalaxieYYYExclClick;
    menFlagVacancesIgnr.Tag     := menFlagVacancesIncl.Tag;
    menFlagVacancesIgnr.OnClick := menFlagGalaxieZZZIgnoreClick;

    menFlagNewbzIncl.Tag     := CNT_GALAXIE_FLAGS_PROTECTION_NOOB_TROPFAIBLE or CNT_GALAXIE_FLAGS_PROTECTION_NOOB_TROPFORT;
    menFlagNewbzIncl.OnClick := menFlagGalaxieXXXInclClick;
    menFlagNewbzExcl.Tag     := menFlagNewbzIncl.Tag;
    menFlagNewbzExcl.OnClick := menFlagGalaxieYYYExclClick;
    menFlagNewbzIgnr.Tag     := menFlagNewbzIncl.Tag;
    menFlagNewbzIgnr.OnClick := menFlagGalaxieZZZIgnoreClick;

    menFlagPlaneteDetruiteIncl.Tag     := CNT_GALAXIE_FLAGS_PLANETE_NON_OCCUPEE or CNT_GALAXIE_FLAGS_ASTEROIDES;
    menFlagPlaneteDetruiteIncl.OnClick := menFlagGalaxieXXXInclClick;
    menFlagPlaneteDetruiteExcl.Tag     := menFlagPlaneteDetruiteIncl.Tag;
    menFlagPlaneteDetruiteExcl.OnClick := menFlagGalaxieYYYExclClick;
    menFlagPlaneteDetruiteIgnr.Tag     := menFlagPlaneteDetruiteIncl.Tag;
    menFlagPlaneteDetruiteIgnr.OnClick := menFlagGalaxieZZZIgnoreClick;

    menFlagJoueurBloqueIncl.Tag     := CNT_GALAXIE_FLAGS_USER_BLOQUE;
    menFlagJoueurBloqueIncl.OnClick := menFlagGalaxieXXXInclClick;
    menFlagJoueurBloqueExcl.Tag     := menFlagJoueurBloqueIncl.Tag;
    menFlagJoueurBloqueExcl.OnClick := menFlagGalaxieYYYExclClick;
    menFlagJoueurBloqueIgnr.Tag     := menFlagJoueurBloqueIncl.Tag;
    menFlagJoueurBloqueIgnr.OnClick := menFlagGalaxieZZZIgnoreClick;


    


    if bExpSimple = false then begin
       FQuitDirect := false;
	   
    end else begin
       // La fonction OnObjectEnter() va déclencher la creation du timer dynamique
       // et s'occuper de fermer le programme
       
       FQuitDirect := true;

       {$IFDEF DEBUGPROTECTION}
           Status('FormCreate - bExpSimple = TRUE, le programme a expire');
       {$ENDIF}

    end;


    FTokenColorization := nil;

    FBase2DonneesPlanete := TCollectionGalaxiePlanete.Create;


    EnableOrDisableWebActionButton(false);

    FCurrentPlayer.DossierRapportCombat := FDossierApp + 'rc\';
    ForceDirectories(FCurrentPlayer.DossierRapportCombat);





    xwStats          := TCollectionPlayerStats.Create;
    FCurrentPlayer.StatsPlayer := xwStats;
    xwStats          := TCollectionPlayerStats.Create;
    FCurrentPlayer.StatsPlayerFlottes := xwStats;
    xwStats          := TCollectionPlayerStats.Create;
    FCurrentPlayer.StatsPlayerRecherche := xwStats;

    // les stats ne sont pas partagée et doivent être libéré
    FCurrentPlayer.StatsShared := false;


    FStatsAlliance        := TCollectionPlayerStatsAllX.Create;
    FStatsAlliance.StatsGlobal    := FCurrentPlayer.StatsPlayer;
    FStatsAlliance.StstsFlottes   := FCurrentPlayer.StatsPlayerFlottes;
    FStatsAlliance.StatsRecherche := FCurrentPlayer.StatsPlayerRecherche;


    
    i := 0;



    //
    // Translation
    //
    TranslateComponent(Self);

    Status('Language: ' + GetCurrentLanguage);

    LoadLanguageFileListForMenu;

    //RefreshLangCombo;




    {$IFNDEF NO_LISTATT}
        chkListeDattenteTraitementActive.Enabled := true;
        lblLAInfos.Caption := '';

    {$ELSE}
        // pas d'attaque auto
        chkListeDattenteTraitementActive.Checked := false;
        chkListeDattenteTraitementActive.Enabled := false;

        lblLAInfos.Caption := _('Version SANS attaques automatiques');

        Status(_('Attaques automatiques: Non supportées dans cette version'));
    {$ENDIF}
    
    {$IFDEF NO_TIME_LIMIT}
       Status(_('Option: Pas de limite dans le temps'));
    {$ENDIF}
    {$IFDEF OFFICIER_OK}
       Status(_('Option: Fonctionne avec les officiers'));
    {$ENDIF}


    ////////////////////////////////////////////////////////////////////////
    // Le chargement s'effectue après que tous les éléments soient créé

  (*
    if LastProfilLoaded <> '' then begin
       i := lstProfilsList.Items.IndexOf(LastProfilLoaded);

       if i >= 0 then
          lstProfilsList.Selected[i] := true;


       if chkLoadAutoProfil.Checked then begin
          if pos(':', LastProfilLoaded) = 0 then
             LastProfilLoaded := Global_DossierProfils + LastProfilLoaded;

          LoadProfilFullPath(LastProfilLoaded);
       end;

    end;
*)



    // Le chargement de profil est obligatoire et se fait par une autre fenetre
    // On affiche donc directement la page de configuration du profil
    //pcSwitch.ActivePageIndex     := tabProfilSelection.PageIndex;
    pcSwitch.ActivePageIndex     := tabProfilsEdit.PageIndex;



    pcProfil.ActivePageIndex     := tabProfilGeneral.PageIndex;
    pcEspionnage.ActivePageIndex := tabEspionnageIn.PageIndex;

    pcInformations.ActivePageIndex    := tabNews.PageIndex;
    pcUniversRapports.ActivePageIndex := tabEspionnage.PageIndex;


    FCurrentPlayer.CallBackOnItemsCostChange := playerOnItemsCostChange;

    FCurrentPlayer.UnitsInfos := FUnitesInformations;
    FCurrentPlayer.GidToStr   := FGidToStr;


    SetWebPagesSaving;

    FChampDeRuineList   := TCollectionGalaxyTriee.Create;



    // CNT_LOCALSETTING_DATE_PremierLancement
    if Global_LocalSetting.ConfGet64(CNT_LOCALSETTING_DATE_PremierLancement) < 1500 then begin
       // premier lancement...
       Global_LocalSetting.ConfSet64(CNT_LOCALSETTING_DATE_PremierLancement, DateTimeToUnix(Now));

       {$IFNDEF NO_LICENCE}
         goto lWizardLicenceStart;
       {$ENDIF}
    end;

{$IFNDEF NO_LICENCE}
    if Global_LocalSetting.ConfGet64(CNT_LOCALSETTING_DATE_LastLicenceWizardShow) < 700 then begin
lWizardLicenceStart:
       // affiche la licence
       formFLX := TformFLX.Create(Self);
       formFLX.StartWizard;

       if formFLX.IsInvalideFiles then begin
          Application.Terminate;
          formFLX.Free;
          exit;
       end;

       if formFLX.ModalResult = WIZARD_LICENCE_MODAL_RES_CANCEL then begin
          // l'utilisateur n'est pas allé jusqu'au bout...
          // on quitte le programme
lWizardLicenceEchec:
          Application.Terminate;
          formFLX.Free;
          exit;
       end;

       if formFLX.LicenceDate < 700 then begin
          // bizarre...
          goto lWizardLicenceEchec;
       end;

       // sauvegarde la date de la licence
       Global_LocalSetting.ConfSet64(CNT_LOCALSETTING_DATE_LicenceDateAccepted, formFLX.LicenceDate);

       // sauvegarde la date d'affichage de la licence
       Global_LocalSetting.ConfSet64(CNT_LOCALSETTING_DATE_LastLicenceWizardShow, DateTimeToUnix(Now));


       Global_LocalSetting.SaveToFile('', [lsoEnteteValues]);

       formFLX.Free;

    end else begin
       // sinon on vérifie quand même si les fichiers sont valide...
       // au moins la licence
       if IsValideLicenceFile = false then begin
          // affiche l'assistant
          goto lWizardLicenceStart;
       end;

    end;
{$ENDIF}



    if Global_LocalSetting.ConfGet(CNT_LOCALSETTING_CurrVersion) < CNT_INT_CURR_VERSION then begin
       // on vient de mettre à jour le robot

       // Definit les nouvelles options
       if Global_LocalSetting.ConfGet(CNT_LOCALSETTING_CurrVersion) < 351 then begin
          Global_LocalSetting.ConfSetBool(CNT_LOCALSETTING_BOOL_DL_NewsAUTO, true);
       end;



       // sauvegarde la nouvelle version
       Global_LocalSetting.ConfSet(CNT_LOCALSETTING_CurrVersion, CNT_INT_CURR_VERSION);

    end;

    chkNewsDLAuto.Checked := Global_LocalSetting.ConfGetBool(CNT_LOCALSETTING_BOOL_DL_NewsAUTO);


    if Global_LocalSetting.ConfLoadTheLastestProfilAtStarup <> 0 then begin
       // on charge le dernier profil
       LastProfilLoaded := Global_DossierProfils + Global_LocalSetting.IniLastProfilLoaded;

       if FileExists(LastProfilLoaded) then begin
          // charge le profil
          Status(_('Charge le dernier profil'));
          LoadProfilFullPath(LastProfilLoaded);

       end else begin
          Status(_('Dernier profil chargé inexistant...'));
          goto lShowProfilSelection;
       end;

    end else begin

  lShowProfilSelection:
       if formProfilChoix = nil then begin
          formProfilChoix := TformProfilChoix.Create(Self);
       end;

       formProfilChoix.PrepareToShow(false);

       Self.Visible := false;

       formProfilChoix.ShowModal;

       if formProfilChoix.ProfilToLoad = '' then begin
          // aucun profil à charger et aucun n'a été créé
          // on ferme le programme
          formProfilChoix.Free;


          Application.Terminate;
          exit;
       end;

       LoadProfilFullPath(formProfilChoix.ProfilToLoad);

       formProfilChoix.Free;
       formProfilChoix := nil;

    end;


    {$IFDEF AUTH_FILE_USE}
       if FQuitDirect = false then begin
          sTempFile :=  AppPath + CNT_FILE_INFOS_LICENCE;

          try
             StreamKey := TFileStream.Create(sTempFile, fmOpenReadWrite);
          except
             StreamKey := nil;
          end;

          if StreamKey <> nil then begin
             FLicenceKeyMemory := TMemoryStream.Create;
             FLicenceKeyMemory.CopyFrom(StreamKey, StreamKey.Size);

          end else begin
             FLicenceKeyMemory := nil;
          end;


       end;

    {$ENDIF}



    msgInitDistanceColor;

    seTransportMassifHumanIntervalleMinChange(nil);
    

    timServiceDelayCmd.Interval := 1500;
    timAdditionnal.Interval     := 1000;





    Self.Visible := true;



    AppPath := '';

    Memo4.Lines.Clear;
    //Memo4.Lines.Add(iaRSADecryptageKeyStream(AppPath, RSA_GetPublicKey, CNT_PUBLICKEY_PASSPHRASE));

{$IFDEF AUTH_FILE_USE}
    if StreamKey <> nil then begin
       StreamKey.Free;
       FLicenceKeyMemory.Seek(0, soBeginning);
    end;

{$ENDIF}

    
end;

procedure TfrmRapportHistorique.cmdEffacerClick(Sender: TObject);
begin
   //txtRapport.Lines.Clear;
end;

procedure TfrmRapportHistorique.cmdEffectuerTransportMassifClick(Sender: TObject);
label lFin;
var i: integer;
    pCible: TPlanetLocation;
    pFrom: TPlanetLocation;
    r: integer;
    iSpeedRatio: integer;
    bDoPause, bHasBeenCanceled: boolean;
begin
   cmdEffectuerTransportMassif.Enabled := false;
   FCurrentPlayer.ProcRecolteArret := false;

   if FCurrentPlayer.IsLoggedAndCanDoSomething = false then begin
      lblTransportMassifEtat.Caption := _('Pas loggé');

      goto lFin;
   end;

   if lstcMassiveTransportPlanetes.Items.Count = 0 then begin
      lblTransportMassifEtat.Caption := _('Pas de planète dans la liste');
      goto lFin;
   end;

   if FCurrentPlayer.IsInTimer then begin
      lblTransportMassifEtat.Caption := _('Une autre opération est déjà en cours');
      goto lFin;
   end;



   pCible := SpiderGalaxieTextPlaneteToLocation(cbMassiveTransportDest.Text);

   if pCible.Galaxie < 1 then begin
      lblTransportMassifEtat.Caption := _('Planète cible invalide');
      goto lFin;
   end;

   if (chkMTUseGT.Checked = false) and (chkMTUsePT.Checked = false)  then begin
      lblTransportMassifEtat.Caption := _('Méthode de sélection des vaisseaux invalide');
      goto lFin;
   end;

    if cbTransportMassifSpeed.ItemIndex < 0 then
       cbTransportMassifSpeed.ItemIndex := 0;
    iSpeedRatio := 10 - cbTransportMassifSpeed.ItemIndex;


   Status(format(_('Deplacement des ressources vers: %s'), [mbtPlanetLocationToStr(pCible)]));


   if NoT(FCurrentPlayer.LockTimer) then begin
      lblTransportMassifEtat.Caption := _('Une autre opération est déjà en cours');

      goto lFin;
   end;


   bDoPause := false;
   Randomize;


   // MethodRemplissageVaisseaux
   if optDeplMethodMCD.Checked then begin
      FCurrentPlayer.MethodRemplissageVaisseaux := rmMetalCristalDeuterium;

   end else if optDeplMethodCDM.Checked then begin
      FCurrentPlayer.MethodRemplissageVaisseaux := rmCristalDeuteriumMetal;

   end else if optDeplMethodCMD.Checked then begin
      FCurrentPlayer.MethodRemplissageVaisseaux := rmCristalMetalDeuterium;

   end else if optDeplMethodDCM.Checked then begin
      FCurrentPlayer.MethodRemplissageVaisseaux := rmDeuteriumCristalMetal;

   end else if optDeplMethodMDC.Checked then begin
      FCurrentPlayer.MethodRemplissageVaisseaux := rmMetalDeuteriumCristal;

   end else if optDeplMethodDMC.Checked then begin
      FCurrentPlayer.MethodRemplissageVaisseaux := rmDeuteriumMetalCristal;

   end else begin
      lblTransportMassifEtat.Caption := _('Erreur de definition de l''ordre de priorité des ressources');

      goto lFin;
   end;




   bHasBeenCanceled := false;


   for i := 0 to lstcMassiveTransportPlanetes.Items.Count - 1 do begin

       if lstcMassiveTransportPlanetes.Checked[i] then begin


             if FCurrentPlayer.ProcRecolteArret then begin
                Status(lblTransportMassifEtat.Caption);
                bHasBeenCanceled := true;
                break;
             end;


          if bDoPause then begin
             r := Random(seTransportMassifHumanComplHuman.Value);
             r := r + seTransportMassifHumanIntervalleMin.Value;
             r := r + 1;

             lblTransportMassifEtat.Caption := format(_('Pause d''humanisation de %d secondes'), [r]);
             FCurrentPlayer.DoSleep(r * 1000);
             if FCurrentPlayer.ProcRecolteArret then begin
                lblTransportMassifEtat.Caption := _('Action annulée');
                Status(lblTransportMassifEtat.Caption);
                bHasBeenCanceled := true;
                break;
             end;
          end;

          pFrom := SpiderGalaxieTextPlaneteToLocation(lstcMassiveTransportPlanetes.Items.Strings[i]);



          Status(format(_('Planete traitée: %s'), [mbtPlanetLocationToStr(pFrom)]));

          lblTransportMassifEtat.Caption := format('En cours: %s', [mbtPlanetLocationToStr(pFrom)]);

          if CompareLocation(pFrom, pCible) then begin
             // meme planete
             Status(_('Ignorée car correspond à la planete cible'));
             Continue;
          end;


          if pFrom.Galaxie < 1 then begin
             Status(_('Echec d''extraction des coordonnées'));
             break;
          end;

          r := FCurrentPlayer.ChangePlanete(pFrom, True);

          if r  = CNT_ERROR_SOCKET then begin
             FCurrentPlayer.DoSleep(1500);

             if FCurrentPlayer.ChangePlanete(pFrom, True) < 0 then begin
                // echec
                Status(_('Echec de changement de planète (second essai)'));

                break;
             end;

          end else if r < 0 then begin
             Status(_('Echec de changement de planète'));

             break;
          end;

          // on déplace les ressources
          r := FCurrentPlayer.DeplacementRessource(pCible,
                                              chkMTMemeSiFretTropFaible.Checked,
                                              chkMTUseGT.Checked, chkMTUsePT.Checked,
                                              chkMTUsePTPreference.Checked,
                                              iSpeedRatio,
                                              optTransportMassifOrdreStationner.Checked);

                                              
          // on fait la pause que si l'envoi est réussi
          bDoPause := false;

          if r < 1 then begin
             Status('Echec de deplacement des ressources, r=' + IntToStr(r));

          end else begin
             if r = 1 then begin
                Status(_('Reussi'));

                bDoPause := true;

             end else if r = CNT_DEPL_RESSOURCE_NO_VAISSEAUX then begin
                Status(_('Pas de vaisseaux sur cette planete'));

             end else if r = CNT_DEPL_RESSOURCE_NO_PT_NOR_GT then begin
                Status(_('Pas de PT ni de GT sur cette planete'));

             end else if r = CNT_DEPL_RESSOURCE_FRET_TROP_PETIT then begin
                Status(_('Capacité de fret trop petite pour tout transporter'));

             end else if r = CNT_DEPL_RESSOURCE_NO_VAISSEAUX_OPT then begin
                Status(_('Pas de vaisseaux désirés sur cette planete'));


             end else begin
                Status('Resultat inconnu: r=' + IntToStr(r));
             end;

          end;


       end;
   end;

   FCurrentPlayer.UnlockTimer;

   if bHasBeenCanceled = false then begin
      lblTransportMassifEtat.Caption := _('Terminé');
   end;


lFin:

   cmdEffectuerTransportMassif.Enabled := true;

   
end;

procedure TfrmRapportHistorique.FormDestroy(Sender: TObject);
var x: TForm;
    i: integer;
begin

    StopTimers;

    if FFileStatusLogEnable then begin
       CloseFile(FFileStatusLog);
    end;

    // les données sont sauvegardées dans le FormCloseQuery
    // (avant le destroy)
    FLocalSetting.Free;
    FLocalSetting := nil;

    FForumCookies.Free;

    FRemplaceStrForPageWeb.Free;

    if FNewsData <> nil then begin
       FNewsData.Free;
       FNewsData := nil;
    end;

    if FFormCdRMonitorList.Count > 0 then begin
       for i := 0 to FFormCdRMonitorList.Count - 1 do begin
           x := FFormCdRMonitorList.Items[i];
           x.Free;
       end;
    end;
    FFormCdRMonitorList.Free;


    global_sockIRC.Free;

    
    SoundFreeCurrent;
    msndDeinit;
    msndUnloadLibrary;

    FChampDeRuineList.Free;

    FTunnelSessionId.Free;

    FCurrSystemSolaire.Free;
    FBaseCurrSystemSolaire.Free;

    //FCurrentProfil.Free;
    //FCurrentProfil := nil;

    FStatsGetFileRecent.Free;

    //FSondagePlanetesList.Free;
    //FSondesAttaqueList.Free;



    FBase2DonneesPlanete.Free;
    //FLanguageList.Free;

    FBase2DonneesRapports.Free;
    FBaseRecent.Free;
    FBaseVacheAlaid.Free;
    FBaseFiltree.Free;

    if FCurrentPlayer.StatsShared = false then begin
       if FCurrentPlayer.StatsPlayer <> nil then begin
          FCurrentPlayer.StatsPlayer.Free;
       end;
       if FCurrentPlayer.StatsPlayerFlottes <> nil then begin
          FCurrentPlayer.StatsPlayerFlottes.Free;
       end;
       if FCurrentPlayer.StatsPlayerRecherche <> nil then begin
          FCurrentPlayer.StatsPlayerRecherche.Free;
       end;
    end;

    if FCurrentPlayer.Conf <> nil then begin
       FCurrentPlayer.Conf.Free;
       FCurrentPlayer.Conf := nil;
    end;

    FCurrentPlayer.Free;
    FCurrentPlayer := nil;
    
    FUnitesInformations.Free;

    TrayIconDestroy;
end;

function TfrmRapportHistorique.LoadBaseDeDonnees(FichierFull: string): integer;
var r: integer;
begin


    {$IFDEF DEBUG}
        Status('LoadBaseDeDonnees: ' + FichierFull);
    {$ENDIF}

    if FBase2DonneesRapports.ExistSomeDataToSave then begin
       r := MessageBoxW(Handle, PWideChar(_('La base de données précédente n''a pas été sauvegardée, voulez vous continuer ?')), PWideChar(_('Remarque')), MB_YESNOCANCEL + MB_ICONQUESTION);

       if r <> ID_YES then begin
          // L'utilisateur à choisit Non ou Annuler
          exit;

       end;

    end;


    // Efface les listes de pointeurs
    FBaseRecent.Clear;
    FBaseVacheAlaid.Clear;
    FBaseCurrSystemSolaire.Clear;
    FBaseFiltree.Clear;


    if FichierFull = '' then begin
       FBase2DonneesRapports.Clear;
       UpdateAll;
       Result := 1;
       exit;
    end;

    Result := FBase2DonneesRapports.LoadFromFile(FichierFull);

    
    lblNbPlanetesLoaded.Caption := IntToStr(FBase2DonneesRapports.Count);

    FBaseRecent.ImportRecent(FBase2DonneesRapports, seDureeForRecent.Value);
    FBaseRecent.TrieParGT;

    FChampDeRuineList.Clear;
    FChampDeRuineList.ImportChampDeRuine(FBase2DonneesPlanete, DateTimeToUnix(Now) - seDureeForRecent.Value);

    FBaseVacheAlaid.ImportVachesAlaid(FBase2DonneesRapports);
    FBaseVacheAlaid.TrieDuree;

    UpdateAll;
end;


procedure TfrmRapportHistorique.cmdDbLoadClick(Sender: TObject);
var i, r: integer;
    Fichier: string;
begin

    if lstFilesDB.Items.Count = 0 then exit;

    Fichier := '';
    for i := 0 to lstFilesDB.Items.Count - 1 do begin
        if lstFilesDB.Selected[i] then begin
           Fichier := lstFilesDB.Items.Strings[i];
           break;
        end;
    end;

    LoadBaseDeDonnees(FDossierDB + Fichier);

end;

procedure TfrmRapportHistorique.sgPlanetesClickCell(Sender: TObject; ARow, ACol: Integer);
var i: integer;
begin

    // gbPlanete
    i := ARow - 1;

    if (i < 0) or (i >= FBase2DonneesRapports.Count) then exit;

    FCurrentRapport := FBase2DonneesRapports.Items[i];
    FRowCurrentRapport := ARow;
    LoadCurrentInForm;
end;

procedure TfrmRapportHistorique.cmdAddAttackNowClick(Sender: TObject);
var CurrDate: int64;
begin

    CurrDate := DateTimeToUnix(Now);

    if mrInjectOnlyIfNeed(FCurrentRapport.DateLastAttaque, CurrDate) then begin
       seNbAttaque.Value := seNbAttaque.Value + 1;
    end;

end;


function TfrmRapportHistorique.RefreshRapportLignes(peRapport: PRapportHead): integer;
var i: integer;
    peGalaxie: PGalaxiePlanete;
begin


    // Raffraichi la ligne
    i := FBase2DonneesRapports.IndexOf(peRapport);
    if i >= 0 then begin
       Inc(i);

       peGalaxie := FBase2DonneesPlanete.Get_Pointeur(peRapport.PlaneteLocation);

       //UpdateData(i, peRapport, sgPlanetes);
       //msgUpdateRapportRow(sgPlanetes, i, peRapport, peGalaxie, cbAttaquePlanete.Text, FCurrentPlayer);


       // Element recent
       i := FBaseRecent.IndexOf(peRapport);
       if i >= 0 then begin
          Inc(i);
          //UpdateData(i, peRapport, sgPlanetesRecentes);
          msgUpdateRapportRow(sgPlanetesRecentes, i, peRapport, peGalaxie, cbAttaquePlanete.Text, FCurrentPlayer);
       end;

       // Vache a laid
       i := FBaseVacheAlaid.IndexOf(peRapport);
       if i >= 0 then begin
          Inc(i);
          //UpdateData(i, peRapport, sgPlanetesPoulesDor);
          msgUpdateRapportRow(sgPlanetesPoulesDor, i, peRapport, peGalaxie, cbAttaquePlanete.Text, FCurrentPlayer);
       end;

       // Elements filtrés
       i := FBaseFiltree.IndexOf(peRapport);
       if i >= 0 then begin
          Inc(i);
          //UpdateData(i, peRapport, sgFiltrer);
          msgUpdateRapportRow(sgFiltrer, i, peRapport, peGalaxie, cbAttaquePlanete.Text, FCurrentPlayer);
       end;

       Result := 1;

    end else
       Result := 0;

end;



procedure TfrmRapportHistorique.cmdUpdatePlaneteClick(Sender: TObject);
var i: integer;
begin
    if FCurrentRapport = nil then exit;

    FCurrentRapport.NbEspionnage := seNbSondage.Value;
    FCurrentRapport.NbAttack     := seNbAttaque.Value;

    if chkTropBienDef.Checked then
       sfcFlagsAdd(FLAG_TROP_BIEN_DEF, FCurrentRapport.Flags)
    else
       sfcFlagsDel(FLAG_TROP_BIEN_DEF, FCurrentRapport.Flags);

    if chkNivEspEleve.Checked then
       sfcFlagsAdd(FLAG_NIV_ESP_ELEVE, FCurrentRapport.Flags)
    else
       sfcFlagsDel(FLAG_NIV_ESP_ELEVE, FCurrentRapport.Flags);

    if chkNeJamaisAttaquer.Checked then
       sfcFlagsAdd(FLAG_NE_JAMAIS_ATTACK, FCurrentRapport.Flags)
    else
       sfcFlagsDel(FLAG_NE_JAMAIS_ATTACK, FCurrentRapport.Flags);

    if chkPouleAuxOeufsDor.Checked then
       sfcFlagsAdd(FLAG_POULE_AUX_OEUFS_DOR, FCurrentRapport.Flags)
    else
       sfcFlagsDel(FLAG_POULE_AUX_OEUFS_DOR, FCurrentRapport.Flags);

    if chkTropPeuDev.Checked then
       sfcFlagsAdd(FLAG_MODE_TROP_PEUDEV, FCurrentRapport.Flags)
    else
       sfcFlagsDel(FLAG_MODE_TROP_PEUDEV, FCurrentRapport.Flags);

    if chkNePasSonderPourCetteSession.Checked then
       sfcFlagsAdd(FLAG_NEPAS_SONDER_TEMPORAIREMENT, FCurrentRapport.Flags)
    else
       sfcFlagsDel(FLAG_NEPAS_SONDER_TEMPORAIREMENT, FCurrentRapport.Flags);

    if chkPlaneteARecycler.Checked then
       sfcFlagsAdd(FLAG_A_RECYCLER, FCurrentRapport.Flags)
    else
       sfcFlagsDel(FLAG_A_RECYCLER, FCurrentRapport.Flags);

    if chkPlaneteDejaRecycler.Checked then
       sfcFlagsAdd(FLAG_DEJA_RECYCLER, FCurrentRapport.Flags)
    else
       sfcFlagsDel(FLAG_DEJA_RECYCLER, FCurrentRapport.Flags);




    RefreshRapportLignes(FCurrentRapport);


    FCurrentRapport.bShouldBeUpdateFixed := true;
    FBase2DonneesRapports.SaveToFile('');
    
    
end;

procedure TfrmRapportHistorique.RefreshDbList;
var NbFound: longword;
    Token: string;
begin



    Token := sfcFileEnumFichiersDir(FDossierDB, '*.od', '%s', ':', NbFound);

    lstFilesDB.Items.Clear;

    sfcStrListTokensCollect(Token, lstFilesDB.Items, ':');
    

end;

procedure TfrmRapportHistorique.CreateBaseDeDonneesFile(Fichier: string);
var FIn: TFileStream;
    i: integer;
begin

    if pos('.od', lowercase(Fichier)) = 0 then
       Fichier := Fichier + '.od';

    if pos(':', Fichier) = 0 then
       Fichier := FDossierDB + Fichier;

    if FileExists(Fichier) = false then begin
        FIn := TFileStream.Create(Fichier, fmCreate);
        FIn.Free;
        FIn := nil;
    end;

end;


procedure TfrmRapportHistorique.cmdCreateDBUseItClick(Sender: TObject);
var FichierDB, FullFichier: string;
    FIn: TFileStream;
    i: integer;
begin

    FichierDB := txtNewBDD.Text;
    CreateBaseDeDonneesFile(FichierDB);

    RefreshDbList;

    // Cherche l'élément dans la liste
    i := lstFilesDB.Items.IndexOf(FichierDB);

    if NoT(i < 0) then begin
       lstFilesDB.Selected[i] := true;
    end;

    
end;



procedure TfrmRapportHistorique.timMonitorClipboardTimer(Sender: TObject);
var r: integer;
    sClipboard: string;
    pe: PPlayerStats;
begin
    try
      sClipboard := Clipboard.AsText;
    except
      sClipboard := '';
    end;

    if (sClipboard = '') or (FLastClipboard = sClipboard) then begin
       exit;
    end;

    FLastClipboard := sClipboard;


    if FCurrentPlayer = nil then begin
       // aucun profil de chargé puisque le joueur n'existe pas
       exit;
    end;


    if pos(#$0D, FLastClipboard) = 0 then begin
       // Il y a qu'une seule ligne
       // Probablement un nom de joueur



       if frmInfoPlayer <> nil then begin
          frmInfoPlayer.SetStatsCollectionTotal(FCurrentPlayer.StatsPlayer);
          frmInfoPlayer.SetStatsCollectionFlottes(FCurrentPlayer.StatsPlayerFlottes);

          frmInfoPlayer.SetCurrentPlayerPointFlottes(FCurrentPlayer.Conf.LimitStFlotte);
          frmInfoPlayer.SetCurrentPlayerPointTotal(FCurrentPlayer.Conf.LimitStGlobal);

          frmInfoPlayer.SetAlliancesAlliees(FCurrentPlayer.Conf.AlliancesAlliees);
       end;



       pe := FCurrentPlayer.StatsPlayer.Get_Pointeur(trim(FLastClipboard));
       if pe <> nil then begin
          frmInfoPlayer.ShowPlayer(pe);

       end else begin
          r := FCurrentPlayer.StatsPlayer.GetFromMask('*' + trim(FLastClipboard) + '*');

          if r > 0 then
             frmInfoPlayer.ShowListFromMaskRes;

       end;

    end else begin
       txtRapport.Text := FLastClipboard;

       // analyse
       r := AnalyseRapportCurr;


       if (r > 0) and (FRapportLastAdd <> nil) then begin
          {$IFDEF DEBUG}
              Status('Presse-Papier - Rapport ajouté: ' + mbtPlanetLocationToStr(FRapportLastAdd.PlaneteLocation));
          {$ENDIF}

           formConfirmation.ShowAdv(FRapportLastAdd, r);
       end;

    end;

    
end;

procedure TfrmRapportHistorique.Copier1Click(Sender: TObject);
begin

  FLastClipboard   := txtRapportLast.Text;
  Clipboard.AsText := FLastClipboard;

end;

procedure TfrmRapportHistorique.cmdStatsLoadClick(Sender: TObject);
begin
    LoadStatsFileForUnivers(seStatsUni.Value);
    frmInfoPlayer.SetCurrentPlayerPointTotal(seCurrPlayerPoints.Value);
end;

procedure TfrmRapportHistorique.seCurrPlayerPointsChange(Sender: TObject);
begin
    frmInfoPlayer.SetCurrentPlayerPointTotal(seCurrPlayerPoints.Value);
end;


procedure TfrmRapportHistorique.cmdTest0887Click(Sender: TObject);
(* {$IFDEF AUTH_FILE_USE}
var myCheck: TLicenceKeyChecking;
{$ENDIF}    *)
var x: TOGRessourceAll;
begin
   // FormFLX.StartWizard;

    
    Status(ESBDGetDureeStrings(127833, true));

    x.Metal   := 3408907;
    x.Cristal := 852226;

    x := FUnitesInformations.GetCout(1, 28);

    Status(ESBDGetDureeStrings(mfdgGetTempsConstructionBatiment(x, 11, 2), true));

end;

procedure TfrmRapportHistorique.cmdTestClick(Sender: TObject);
var str: string;
    F: TFileStream;
begin

(*
   // str =
   F := TFileStream.Create('D:\DelphiMain\Projects\Divers\Ogame\PageTest\galaxie.txt', fmOpenRead);

   SetLength(str, F.Size);

   F.Read(str[1], F.Size);

   txtDebug1.Text := str;

   F.Free;
*)

end;

procedure TfrmRapportHistorique.cmdTestEvaClick(Sender: TObject);
begin
    FCurrentPlayer.EvacuationSurChampDeRuineOuInactif(FCurrentPlayer.curPlanete.FLocation, 75);
end;

procedure TfrmRapportHistorique.sgPlanetesRecentesClickCell(Sender: TObject; ARow, ACol: Integer);
var i: integer;
begin

    // gbPlanete
    i := ARow - 1;

    if (i < 0) or (i >= FBaseRecent.Count) then exit;

    FCurrentRapport := FBaseRecent.Items[i];
    FRowCurrentRapport := ARow;
    LoadCurrentInForm;
end;

procedure TfrmRapportHistorique.cmdBDDUpgradeV2toV3Click(Sender: TObject);
var i, r: integer;
    Fichier: string;
begin


(*
    if lstFilesDB.Items.Count = 0 then exit;

    Fichier := '';
    for i := 0 to lstFilesDB.Items.Count - 1 do begin
        if lstFilesDB.Selected[i] then begin
           Fichier := lstFilesDB.Items.Strings[i];
           break;
        end;
    end;

    if Fichier = '' then exit;

    if FBase2Donnees.ExistSomeDataToSave then begin
       r := Application.MessageBox('La base de données précédente n''a pas été sauvegardé, voulez vous continuer ?', 'Remarque', MB_YESNOCANCEL + MB_ICONQUESTION);

       if r <> ID_YES then begin
          // L'utilisateur à choisit Non ou Annuler
          exit;

       end;

    end;

    FBase2Donnees.LoadFromFile(FDossierDB + Fichier, CNT_FORMATSAVE_VERSION2);
    FBase2Donnees.PrepareFlagForFullSave;
    DeleteFile(FDossierDB + Fichier);
    FBase2Donnees.SaveToFile('');
*)

end;

procedure TfrmRapportHistorique.N1heure1Click(Sender: TObject);
begin
   seDureeForRecent.Value := 3600;
end;

procedure TfrmRapportHistorique.N2heure1Click(Sender: TObject);
begin
   seDureeForRecent.Value := 3600 * 2;
end;

procedure TfrmRapportHistorique.N3heure1Click(Sender: TObject);
begin
   seDureeForRecent.Value := 3600 * 3;
end;

procedure TfrmRapportHistorique.N5heures1Click(Sender: TObject);
begin
   seDureeForRecent.Value := 3600 * 5;
end;

procedure TfrmRapportHistorique.N8heures1Click(Sender: TObject);
begin
   seDureeForRecent.Value := 3600 * 8;
end;

procedure TfrmRapportHistorique.N12heures1Click(Sender: TObject);
begin
   seDureeForRecent.Value := 3600 * 12;
end;

procedure TfrmRapportHistorique.N1jour1Click(Sender: TObject);
begin
   seDureeForRecent.Value := 3600 * 24;
end;

procedure TfrmRapportHistorique.N2jours1Click(Sender: TObject);
begin
   seDureeForRecent.Value := 3600 * 24 * 2;
end;

procedure TfrmRapportHistorique.N4jours1Click(Sender: TObject);
begin
   seDureeForRecent.Value := 3600 * 24 * 4;
end;

procedure TfrmRapportHistorique.cmdAppliqueAnciennetesClick(Sender: TObject);
begin
    FBaseRecent.Clear;
    FBaseRecent.ImportRecent(FBase2DonneesRapports, seDureeForRecent.Value);
    FBaseRecent.TrieParGT;

    UpdateAllSpec(sgPlanetesRecentes, FBaseRecent);


     FChampDeRuineList.Clear;
     FChampDeRuineList.ImportChampDeRuine(FBase2DonneesPlanete, DateTimeToUnix(Now) - seDureeForRecent.Value);
     sggUpdateChampsDeRuine(sgChampDeRuines, FChampDeRuineList, FBase2DonneesRapports, FCurrentPlayer);
end;

procedure TfrmRapportHistorique.cmdScanAllianceClick(Sender: TObject);
begin
   FStatsAlliance.ScanAlliance(txtAlliance.Text);
   UpdateStatsAlliance(gdStats);
end;


procedure TfrmRapportHistorique.tOnTimerDyn(Sender: TObject);
begin
	// Le programme doit cesser de fonctionner
end;


function TfrmRapportHistorique.GetRelativeDBPath(Fichier: string): string;
var lng: integer;
    sCmp: string;
begin

    lng := length(FDossierDB);

    sCmp := copy(Fichier, 1, lng);

    if SameText(sCmp, FDossierDB) then begin
       Result := copy(Fichier, lng + 1, maxint);
    end else
       Result := Fichier;


end;

procedure TfrmRapportHistorique.cmdLoadDBFromProfilsClick(Sender: TObject);
label lblUsed;
var iGalaxie: integer;
    Fichier, FichierGalaxie: string;
    bDontLoadFromFileRapport: boolean;
begin
    // seDBGalaxie
    // DossierDB: FDossierDB

    // Contrairement aux fichiers stats, les bases de donnees sont toutes
    // utiles, et on ne peut donc pas prendre la plus recente

    // On verifie dans un premier temps si un fichier est
    // definit dans le profil

    if cmdLoadDBFromProfils.Enabled = false then exit;

    cmdLoadDBFromProfils.Enabled := false;


    Status(format(_('Sondage - Toutes les planètes ont été effacé (%d  éléments)'), [FCurrentPlayer.SondagePlanetesList.Count]));
    FCurrentPlayer.SondagePlanetesList.Clear;


    iGalaxie := seDBGalaxie.Value;


    bDontLoadFromFileRapport := false;


    {$IFDEF DEBUG}
        Status('----------');
        Status(format(_('Chargement des bases de donnees pour la galaxie: %d'), [iGalaxie]));
    {$ENDIF}

    FBase2DonneesPlanete.Clear;

    if (iGalaxie < 1) or (iGalaxie > 50) then begin
       lblProfilFichierRapportDB.Caption := 'Hors limite';
       lblProfilFichierRapportDB.Font.Color := clRed;

       {$IFDEF DEBUG}
          Status(format(_('Galaxie hors limite: %d'), [iGalaxie]));
       {$ENDIF}

       cmdLoadDBFromProfils.Enabled := true;
       exit;
    end;

    Fichier := FCurrentPlayer.Conf.GetRapportDB(iGalaxie);

    if Fichier <> '' then begin

       {$IFDEF DEBUGFORME}
          Status('Fichier "base de données de rapports" trouve dans le profil: ' + Fichier);
       {$ENDIF}


       if pos(':', Fichier) = 0 then begin
          // c'est un chemin relatif
          Fichier := FDossierDB + Fichier;

          {$IFDEF DEBUGFORME}
             Status('Definition du chemin complet: ' + Fichier);
          {$ENDIF}

       end else begin
          // c'est un chemin complet
          {$IFDEF DEBUG}
             Status(_('Le chemin du fichier est deja complet'));
          {$ENDIF}

       end;


       goto lblUsed;
    end;


    {$IFDEF DEBUG}
        Status(_('Aucun fichier "base de données de rapports" trouve dans le profil, recherche dans le dossier: ') + FDossierDB);
    {$ENDIF}

    // Sinon scan les fichier dans le dossier
    Fichier := GetFileFromScanForThisGalaxie(FCurrentPlayer.Conf.Univers, iGalaxie, tbdRapports);


    if Fichier <> '' then begin
       // extrait le chemin relatif pour la sauvegarde
       FCurrentPlayer.Conf.SetRapportDB(iGalaxie, GetRelativeDBPath(Fichier));
       lblProfilFichierRapportDB.Font.Color := clPurple;
       goto lblUsed;
    end;


    {$IFDEF DEBUG}
        Status(_('Aucun fichier "base de données de rapports" correspondant trouve dans le dossier des bases de donnees'));
    {$ENDIF}

    Fichier := format('Uni%d_Galaxie%d.od', [FCurrentPlayer.Conf.Univers, iGalaxie]);


    {$IFDEF DEBUG}
        Status(_('Creation d''un nouveau fichier: ') + Fichier);
    {$ENDIF}


    // on sauvegarde le chemin relatif
    FCurrentPlayer.Conf.SetRapportDB(iGalaxie, Fichier);

    // definit le chemin complet
    Fichier := FDossierDB + Fichier;

    {$IFDEF DEBUG}
        Status(_('Chemin complet: ') + Fichier);
    {$ENDIF}


    if FileExists(Fichier) then begin
       // Le fichier existe déjà
       Status(_('Erreur, le fichier existe déjà....'));
       
    end else begin
       FBase2DonneesRapports.Univers := FCurrentPlayer.Conf.Univers;
       FBase2DonneesRapports.Galaxie := iGalaxie;
       FBase2DonneesRapports.Clear;

       FBase2DonneesRapports.FichierHeadSave := Fichier;
       FBase2DonneesRapports.SaveToFile('');
       bDontLoadFromFileRapport := true;
    end;


lblUsed:
    //lblProfilFichierRapportDB.Caption := ExtractFileName(Fichier);
    //lblProfilFichierRapportDB.Font.Color := clBlack;


    // Sauvegarde le numero de la galaxie recemment charge
    FCurrentPlayer.Conf.SetLastUsedRapportDB(iGalaxie);




    if FBase2DonneesRapports.Univers < 1 then begin
       FBase2DonneesRapports.Univers := FCurrentPlayer.Conf.Univers;
       FBase2DonneesRapports.Galaxie := iGalaxie;
    end;



    FichierGalaxie := GetFileFromScanForThisGalaxie(FCurrentPlayer.Conf.Univers, iGalaxie, tbdGalaxie);

    if FichierGalaxie <> '' then begin
       FBase2DonneesPlanete.LoadFromFile(FichierGalaxie);
       lblProfilFichierGalaxyDB.Caption := ExtractFileName(FichierGalaxie);
       lblProfilFichierGalaxyDB.Font.Color := clBlue;
       lblNbPlaneteLoadedGalaxy.Caption := IntToStr(FBase2DonneesPlanete.Count);

       lblCurrentGalaxie.Caption := format(_('Galaxie %d'), [iGalaxie]);

    end else begin
       FBase2DonneesPlanete.Clear;
       lblProfilFichierGalaxyDB.Caption := _('Aucun');
       lblProfilFichierGalaxyDB.Font.Color := clPurple;
       lblNbPlaneteLoadedGalaxy.Caption := '';

       lblCurrentGalaxie.Caption := format(_('Galaxie %d (Non chargé)'), [iGalaxie]);
    end;



    if bDontLoadFromFileRapport = false then begin
       if LoadBaseDeDonnees(Fichier) < 0 then begin
          // Echec de chargement de la base de données
          {$IFDEF DEBUG}
              Status(_('Echec de chargement de la "base de données de rapports": ') + Fichier);
              Status(_('Ecrasement du fichier'));
          {$ENDIF}

          FBase2DonneesRapports.Univers := FCurrentPlayer.Conf.Univers;
          FBase2DonneesRapports.Galaxie := iGalaxie;
          FBase2DonneesRapports.Clear;

          FBase2DonneesRapports.FichierHeadSave := Fichier;
          FBase2DonneesRapports.SaveToFile('');
       end;

    end;


    RefreshMenuFiltreCheckbox;

    {$IFDEF DEBUG}
        Status(format(_('Rapport - Galaxie: %d'), [FBase2DonneesRapports.Galaxie]));
        Status(format(_('Rapport - Univers: %d'), [FBase2DonneesRapports.Univers]));
    {$ENDIF}

    FInfosBaseDeDonneCharge := true;
    GalaxieNumeroColorationFromCurrPlanete;



    cbGalaxieScanPlaneteChange(nil);
    cbSondagePlaneteChange(nil);

    
    EnableOrDisableBDDButton(true);
    cmdLoadDBFromProfils.Enabled := true;
end;

procedure TfrmRapportHistorique.cmdProfilEditClick(Sender: TObject);
var frmProfilConf: TformProfilConfig;
begin

    frmProfilConf := TformProfilConfig.Create(Self);

    frmProfilConf.ConfigPlayer(FCurrentPlayer, @FCurrentSound, FLocalSetting, Status);


    LoadProfilInFormLimitation;

    frmProfilConf.Free;


(*
    //InitGrille(sgPlanetes);
    InitGrille(sgPlanetesRecentes);
    InitGrille(sgPlanetesPoulesDor);
    InitGrille(sgFiltrer);
*)

end;

procedure TfrmRapportHistorique.tOnTimerDynClose(Sender: TObject);
begin

    PostMessage(Application.Handle,  WM_CLOSE_MISC - WM_MISC_ADDED, 0, 0);
    FQuitDirect := true;

    {$IFDEF DEBUGPROTECTION}
        Status('PROTECTION >> tOnTimerDynClose - PostMessage WM_CLOSE');
    {$ENDIF}
end;


procedure TfrmRapportHistorique.LoadCorrectGidToStrFile;
label lLoadGrid;
var bLoadDefaut: boolean;
    AppPath: string;
    i, j: integer;
    pGid: PGIDtoSTR;
begin

    bLoadDefaut := true;
    if trim(LangParsing.GidToStrFile) <> '' then begin

       FGidToStr.FichierSave := Global_DossierLang + LangParsing.GidToStrFile;
       FGidToStr.LoadFromFile;

       if FGidToStr.Count < 50 then begin
          Status(format(_('IMPORTANT: Fichier invalide: %s (connu à partir du fichier de langue)'), [FGidToStr.FichierSave]));
          Status(_('Essai de chargement à partir du fichier par defaut'));
       end else begin
          Status(format(_('Fichier GidToStr chargé: %s'), [FGidToStr.FichierSave]));
          goto lLoadGrid;
          exit;
       end;

    end;


    AppPath := ExtractFileDir(Application.ExeName);
    AppPath := IncludeTrailingPathDelimiter(AppPath);

    FGidToStr.FichierSave := AppPath + CONF_GIDTOSTRDEFAULT;
    FGidToStr.LoadFromFile;


    if FGidToStr.Count < 50 then begin
       Status(format(_('IMPORTANT: Fichier GidToStr invalide: '), [FGidToStr.FichierSave]));
       exit;
    end else begin
       Status(format(_('Fichier GidToStr chargé: %s'), [FGidToStr.FichierSave]));
    end;





lLoadGrid:
    //////////////////////////////////////////////////////////////
    // Les noms de planètes en entête de colonne
    // Et les éléments sur à gauche
    i := 0;
    gsPlanet.Cells[0, i] := ''; Inc(i);

    gsPlanet.Cells[0, i] := _('Position'); Inc(i);
    gsPlanet.Cells[0, i] := _('Cases'); Inc(i);

    gsPlanet.Cells[0, i] := _('Construction'); Inc(i);
    gsPlanet.Cells[0, i] := _('Prochaine Action'); Inc(i);
    gsPlanet.Cells[0, i] := _('Actions en attente'); Inc(i);



    gsPlanet.Cells[0, i] := _('Ressource Métal');  Inc(i);
    gsPlanet.Cells[0, i] := _('Ressource Cristal'); Inc(i);
    gsPlanet.Cells[0, i] := _('Ressource Deutérium');  Inc(i);
    gsPlanet.Cells[0, i] := _('Ressource Energie');  Inc(i);
    gsPlanet.Cells[0, i] := _('Ressource validité'); Inc(i); // Dure écoulée depuis la dernière mise à jour des ressources

    gsPlanet.Cells[0, i] := _('Production Métal');  Inc(i);
    gsPlanet.Cells[0, i] := _('Production Cristal'); Inc(i);
    gsPlanet.Cells[0, i] := _('Production Deutérium');  Inc(i);


    gsPlanet.ColWidths[0] := 160;

    if gsPlanet.RowCount > i then begin
       gsPlanet.RemoveRows(i, gsPlanet.RowCount - i);
    end;


    for j := 0 to 13 do begin
       gsPlanet.CellProperties[0, j].Alignment := Classes.taRightJustify;
    end;

    if FGidToStr.Count > 0 then begin
       for j := 0 to FGidToStr.Count - 1 do begin
          pGid := FGidToStr.Items[j];

          if mbtIsValidGID(pGid.GID) then begin
             gsPlanet.AddRow;
             gsPlanet.Cells[0, i] := sfcRemplace(pGid.Valeur, 'Technologie', 'Techno.');
             //gsPlanet.Cells[0, i] := sfcRemplace(pGid.Valeur, 'Technology', 'Techno.');

             gsPlanet.CellProperties[0, i].Alignment := Classes.taRightJustify; Inc(i);
          end;

       end;

    end;

end;

procedure TfrmRapportHistorique.CleanupEverything;
begin

    Status('Clean - Starting...');
    // nettoie le fichier de langue
    LangParsing.Cleanup;

    timAttackNotificationAndOnTimer.Interval := 0;

    timSondage.Interval := 0;

    
    // initialise le profil
    FCurrentPlayer.Conf.InitProfil;


    // intialise le joueur
    FCurrentPlayer.Clear(true);
    FCurrentPlayer.allPlanetes.Clear;

    // La classe du joueur est maintenant très IMPORTANTE
    // car elle contient les statistiques, GidToStr et les informations d'unités
    FCurrentPlayer.ClearStats;


    

    // vide les bases de données
    FBase2DonneesRapports.Clear;
    FBase2DonneesPlanete.Clear;

    // Efface les listes de pointeurs
    FBaseRecent.Clear;
    FBaseVacheAlaid.Clear;
    FBaseCurrSystemSolaire.Clear;
    FBaseFiltree.Clear;



    FInfosBaseDeDonneCharge := false;
    GalaxieNumeroColorationFromCurrPlanete;

    

    Status('Clean - Terminated');

end;

procedure TfrmRapportHistorique.LoadProfilFullPath(FichierFull: string);
var i: integer;
    DateEtHeure : TSystemTime;
begin



    CleanupEverything;

    FCurrentPlayer.Conf.LoadFromFile(FichierFull);
    if FCurrentPlayer.Conf.IsValidProfil = false then begin
       menSpiderLogin.Enabled := false;
       Status(format(_('Profil invalide: %s'), [FichierFull]));
       exit;
    end;

    tabProfilsEdit.Enabled := true;

    if FCurrentPlayer.Conf.LangageUni <> LANG_INTERNAL then begin
       LangParsing.LoadFromFile(Global_DossierLang + FCurrentPlayer.Conf.LangageUni, false);

       if LangParsing.Count < 10 then begin
          Status(format(_('Invalide language file: %s'), [Global_DossierLang + FCurrentPlayer.Conf.LangageUni]));
          Status(_('Using default lang file'));
          LangParsing.Cleanup;

       end else begin
          Status(format(_('Language file loaded: %s'), [Global_DossierLang + FCurrentPlayer.Conf.LangageUni]));



          FCurrentPlayer.lLoginUniversListPage               := LangParsing.LoginURL;
          FCurrentPlayer.lLogingUniversListPageReferenceLink := LangParsing.LoginReference;
          FCurrentPlayer.lSpecialLogin                       := LangParsing.LoginSpecial;
       end;


    end else begin
        Status(_('Langue: Serveur français (ogame.fr), interne au programme (pas de fichier langue)'));
    end;

    // charge le bon fichier GidToStr.txt
    LoadCorrectGidToStrFile;


    menSpiderLogin.Enabled := true;

    // Charge egalement les stats pour cet univers
    LoadStatsFileForUnivers(FCurrentPlayer.Conf.Univers);


    // charge le profil dans la form
    LoadProfilInForm;

    i := FCurrentPlayer.Conf.LastGalaxieUsed;

    if i > 0 then begin
       seDBGalaxie.Value := i;
    end;

    GetSystemTime(DateEtHeure);
    FFileBackupRapport := FDossierApp + format('u%d_backup.txt', [FCurrentPlayer.Conf.Univers]);
    FFileBackupMsgList := FDossierApp + format('u%d_messages.txt', [FCurrentPlayer.Conf.Univers]);
    FFileBackupMsgFlotte := FDossierApp + format('u%d_msgretour.txt', [FCurrentPlayer.Conf.Univers]);



    CreateFile(FFileBackupRapport, DateEtHeure);
    CreateFile(FFileBackupMsgList, DateEtHeure);
    CreateFile(FFileBackupMsgFlotte, DateEtHeure);

    

    // Il faudra recharger la base de données
    EnableOrDisableBDDButton(false);


    // Réinitialise le spider
    FCurrentPlayer.Clear(true);
    FCurrentPlayer.LoadFromFile(FichierFull + '.u');
    FCurrPlayerCurrPlanete := nil;
    FCurrPlayerCurrPlanetForConstruction := nil;


    if FCurrentPlayer.Conf.CapaciteFretCalculMethodUseContrainte then begin
       FCurrentPlayer.ProcForCapacite := mfdgGetFretCapaciteRequiseContrainteSM;
    end else begin
       FCurrentPlayer.ProcForCapacite := mfdgGetFretCapaciteRequise;
    end;
    

    // Raffraichi les données
    RefreshPlanetGrid(FCurrentPlayer);
    RefreshPlanetGridAutoConstruction(FCurrentPlayer);


    SpiderGalaxieSetToScan(seDBGalaxie.Value);
    seDBGalaxieChange(nil);


    if chkLoadAutoGalaxieDB.Checked then begin
       // Géré dans un timer car sinon, lors du lancement du programme
       // cela génère une erreur d'accès
       // cmdLoadDBFromProfilsClick(nil);
    end;

    if FCurrentPlayer.Conf.Univers > 0 then begin

       lblCurrentUnivers.Caption := format(_('Univers %d'), [FCurrentPlayer.Conf.Univers]);

       {$IFDEF AUTH_FILE_USE}
            // Attention, la caption est également modifié ailleurs (dans timLoadLastDBAutoTimer)
            Caption := APP_CAPTION + format(_(' - Univers %d'), [FCurrentPlayer.Conf.Univers]) + ' [v' + CNT_CURR_VERSION + '] ' + FAuthCaption;
       {$ELSE}
            Caption := APP_CAPTION + format(_(' - Univers %d'), [FCurrentPlayer.Conf.Univers]);
       {$ENDIF}

       Application.Title := format(_('Univers %d %s'), [FCurrentPlayer.Conf.Univers, FCurrentPlayer.Conf.Pseudo]);



       lblProfilActuel.Caption := format(_('Profil Actuel - %s (Univers %d)'), [FCurrentPlayer.Conf.Pseudo, FCurrentPlayer.Conf.Univers]);
	

       // Affiche la page de modification du profil
       pcSwitch.ActivePageIndex := tabProfilsEdit.PageIndex;


       if FExisteTrayIcon then
          TrayIconChangeTitle(format(_('Univers %d - %s'), [FCurrentPlayer.Conf.Univers, FCurrentPlayer.Conf.Pseudo]));

    end else begin
       // TODO: Vérouiller le reste de l'application, forcer le choix d'un autre profil
       
       if FExisteTrayIcon then
          TrayIconChangeTitle(format(_('Univers inconnu'), [FCurrentPlayer.Conf.Univers, FCurrentPlayer.Conf.Pseudo]));

       lblCurrentUnivers.Caption := _('Univers inconnu');
       Application.Title := _('Univers Unk');
    end;
       
    // Il faudra se relogger
    EnableOrDisableWebActionButton(false);


    GalaxieNumeroColorationFromCurrPlanete;

    RefreshMenuFiltreCheckbox;
    timLoadLastDBAuto.Interval := 1200;
end;





procedure TfrmRapportHistorique.cmdStatsReloadClick(Sender: TObject);
begin
    cmdStatsReload.Enabled := false;

    // Charge egalement les stats pour cet univers
    LoadStatsFileForUnivers(FCurrentPlayer.Conf.Univers);

    cmdStatsReload.Enabled := true;
end;

procedure TfrmRapportHistorique.OnObjectEnter(Sender: TObject);
var r: string;
begin

    {$IFDEF DEBUGPROTECTION}
          Status('OnObjectEnter');
    {$ENDIF}


end;


procedure TfrmRapportHistorique.scanDirFichier(Sender: TObject; Nom: string);
var CurrDB: TCollectionRapportHead;
begin

    // Fichier base de donnees trouve
    if FScanDB = nil then exit;

    if FScanDB.LoadFromFile(Nom) > 0 then begin
       if FScanDB.Univers = FScanUnivers then begin

          if FScanDB.Galaxie = FScanGalaxie then begin
             // cela correspond
             FScanFileFound := Nom;
             scanDir.StopScan;

          end;

       end;

    end;       

end;

procedure TfrmRapportHistorique.seDBGalaxieChange(Sender: TObject);
begin
    SetFileLabelFromGalaxie(seDBGalaxie.Value);
    SpiderGalaxieSetToScan(seDBGalaxie.Value);

    //
end;

procedure TfrmRapportHistorique.seLANbFreeSlotChange(Sender: TObject);
begin
    FCurrentPlayer.NbFreeSlotALaisse := seLANbFreeSlot.Value;
end;

procedure TfrmRapportHistorique.chkNewsDLAutoClick(Sender: TObject);
begin
    Global_LocalSetting.ConfSetBool(CNT_LOCALSETTING_BOOL_DL_NewsAUTO, chkNewsDLAuto.Checked);
    Global_LocalSetting.SaveToFile('', [lsoEnteteValues]);

end;

procedure TfrmRapportHistorique.chkListeDattenteTraitementActiveClick(
  Sender: TObject);
begin
    FCurrentPlayer.ListeDattaqueActive := chkListeDattenteTraitementActive.Checked;
end;

procedure TfrmRapportHistorique.chkLoadAutoGalaxieDBClick(Sender: TObject);
begin
    //SaveSetting(REG_PROG_NAME, REG_PROG_SECTION_CFG, REG_KEY_LOADGALAXIE_AUTO , chkLoadAutoGalaxieDB.Checked);
    FLocalSetting.ConfLoadTheLastestBDOnProfilLoad := IIF(chkLoadAutoGalaxieDB.Checked, 1, 0);

end;

procedure TfrmRapportHistorique.sgPlanetesPoulesDorClickCell(Sender: TObject; ARow, ACol: Integer);
var i: integer;
begin

    i := ARow - 1;

    if (i < 0) or (i >= FBaseVacheAlaid.Count) then exit;

    FCurrentRapport := FBaseVacheAlaid.Items[i];
    //FRowCurrentRapport := ARow;
    LoadCurrentInForm;
end;

function TfrmRapportHistorique.ColorizeLigne(Ligne: string): string;
begin
    // FTokenColorization
end;

procedure TfrmRapportHistorique.AfficheMsgGalaxy(const Msg: string);
begin
    txtDBPlanetes.Lines.Add(Msg);
end;


procedure TfrmRapportHistorique.AfficheGalaxyPlaneteFlagsOnlyInfos(pe: PGalaxiePlanete);
begin
           if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_MODE_VACANCES, pe.Flags) then
              AfficheMsgGalaxy(_('Flag: Mode vacances'));
           if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_INACTIF_2SEMAINES, pe.Flags) then
              AfficheMsgGalaxy(_('Flag: Inactif 2 semaines'));
           if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_INACTIF_4SEMAINES, pe.Flags) then
              AfficheMsgGalaxy(_('Flag: Inactif 4 semaines'));
           if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_PROTECTION_NOOB_TROPFAIBLE, pe.Flags) then
              AfficheMsgGalaxy(_('Flag: Protection des débutants (trop faible))'));
           if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_PROTECTION_NOOB_TROPFORT, pe.Flags) then
              AfficheMsgGalaxy(_('Flag: Protection des débutants (trop fort)'));
           if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_PLANETE_NON_OCCUPEE, pe.Flags) then
              AfficheMsgGalaxy(_('Flag: Planete non occupée'));
           if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_USER_BLOQUE, pe.Flags) then
              AfficheMsgGalaxy(_('Flag: Utilisateur bloqué'));
end;

procedure TfrmRapportHistorique.AfficheGalaxyPlaneteInfos(pe: PGalaxiePlanete);
begin
           AfficheMsgGalaxy('---------------------------');
           AfficheMsgGalaxy('Position: ' + mbtPlanetLocationToStr(pe.Location));
           AfficheMsgGalaxy(format(_('NomPlanete: %s'), [pe.NomPlanete]));
           AfficheMsgGalaxy(format(_('Joueur: %s')    , [pe.Joueur]));

           if chkScanGalaxieAfficheAlliance.Checked then begin
              AfficheMsgGalaxy(format(_('Alliance: %s')    , [pe.Alliance]));
           end;

           AfficheGalaxyPlaneteFlagsOnlyInfos(pe);

end;


function TfrmRapportHistorique.GetPlaneteTokenForThisPlayer(Joueur: string; sSeparateur: string): string;
var i: integer;
    sRecherche: string;
    pe: PGalaxiePlanete;
begin

    Result := '';

    // txtDBGalaxyJoueur
    if FBase2DonneesPlanete.Count = 0 then exit;

    sRecherche := trim(Joueur);


    for i := 0 to FBase2DonneesPlanete.Count - 1 do begin
        pe := FBase2DonneesPlanete.Items[i];

        if SameText(pe.Joueur, sRecherche) then begin
        
           if Result = '' then
              Result := mbtPlanetLocationToStr(pe.Location)
           else
              Result := Result + sSeparateur + mbtPlanetLocationToStr(pe.Location);


        end;

    end;

end;

procedure TfrmRapportHistorique.cmdGalaxyRechercheJoueurClick(Sender: TObject);
var i: integer;
    sRecherche: string;
    pe: PGalaxiePlanete;
begin

    // txtDBGalaxyJoueur
    if FBase2DonneesPlanete.Count = 0 then exit;



    sRecherche := trim(txtDBGalaxyJoueur.Text);

    AfficheMsgGalaxy('');
    AfficheMsgGalaxy('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
    AfficheMsgGalaxy('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
    AfficheMsgGalaxy(format(_('# Recherche joueur: %s'), [sRecherche]));
    AfficheMsgGalaxy('');


    for i := 0 to FBase2DonneesPlanete.Count - 1 do begin
        pe := FBase2DonneesPlanete.Items[i];

        if SameText(pe.Joueur, sRecherche) then begin
           AfficheGalaxyPlaneteInfos(pe);
        end;

    end;

end;

procedure TfrmRapportHistorique.cmdGalaxyRechercheAllianceClick(
  Sender: TObject);
var i, j: integer;
    sRecherche: string;
    sRechercheList: TStringList;
    
    pe: PGalaxiePlanete;
    sListJoueur, sListAll: TStringList;
    sAdd: string;
begin

    // txtDBGalaxyJoueur
    if FBase2DonneesPlanete.Count = 0 then exit;

    sRecherche := trim(txtDBGalaxyAlliances.Text);

    AfficheMsgGalaxy('');
    AfficheMsgGalaxy('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
    AfficheMsgGalaxy('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
    AfficheMsgGalaxy(format(_('# Recherche alliance: %s'), [sRecherche]));
    AfficheMsgGalaxy('');

    if chkAfficherQueNomJoueur.Checked then begin
       sListJoueur := TStringList.Create;
       sListAll    := TStringList.Create;
    end else begin
       sListJoueur := nil;
       sListAll := nil;
    end;


    for i := 0 to FBase2DonneesPlanete.Count - 1 do begin
        pe := FBase2DonneesPlanete.Items[i];

        if SameText(pe.Alliance, sRecherche) then begin
           if chkAfficherQueNomJoueur.Checked then begin

              j := sListJoueur.IndexOf(pe.Joueur);
              if j < 0 then begin
                 sAdd := pe.Joueur + ' -> ' + mbtPlanetLocationToStr(pe.Location);

                 sListAll.Add(sAdd);
                 sListJoueur.Add(pe.Joueur);

                 AfficheGalaxyPlaneteFlagsOnlyInfos(pe);

              end else begin
                 sAdd := sListAll.Strings[j];
                 sAdd := sAdd + ' , ' + mbtPlanetLocationToStr(pe.Location);
                 sListAll.Strings[j] := sAdd;
              end;

           end else
              AfficheGalaxyPlaneteInfos(pe);
        end;

    end;

    if sListJoueur <> nil then begin
       // Affiche la list
       if sListAll.Count > 0 then begin
          for i := 0 to sListAll.Count - 1 do
             AfficheMsgGalaxy(sListAll.Strings[i]);

       end;

       sListAll.Free;
       sListAll := nil;

       sListJoueur.Free;
       sListJoueur := nil;
    end;


end;

procedure TfrmRapportHistorique.cmdVoirPlaneteInexistanteClick(Sender: TObject);
var i, j: integer;
    pe: PGalaxiePlanete;
    pCurrent: TPlanetLocation;
begin

    pCurrent.Galaxie       := FBase2DonneesPlanete.Galaxie;
    pCurrent.SystemSolaire := 1;
    pCurrent.Position      := 1;

    
    for i := 0 to FBase2DonneesPlanete.Count - 1 do begin
        pe := FBase2DonneesPlanete.Items[i];

        j := 0;

        while CompareLocation(pe.Location, pCurrent) = false do begin
           AfficheMsgGalaxy(format(_('Inexistant: %s'), [mbtPlanetLocationToStr(pCurrent)]));
           mbtIncLocation(pCurrent);
           Inc(j);
           if j > 1000 then break;
        end;

        if j > 1000 then begin
           AfficheMsgGalaxy('Exited');
           break;
        end;

        
        mbtIncLocation(pCurrent);


    end;

    AfficheMsgGalaxy(_('Terminé'));
    

end;

procedure TfrmRapportHistorique.cmdRechercheTokenAllianceClick(Sender: TObject);
var i, j, lng, k: integer;
    sRechercheList, sRechercheListAllies: TStringList;
    
    pe: PGalaxiePlanete;
    sAdd, sTmp, sTmp2: string;
    pStats: PPlayerStats;
    sHTML: string;

    bAllies: boolean;

    GalaxyTriee: TCollectionGalaxyTriee;
begin

    // txtDBGalaxyJoueur
    if FBase2DonneesPlanete.Count = 0 then exit;

    sRechercheList := TStringList.Create;
    sfcStrListTokensCollect(txtDBGalaxyAlliances.Text, sRechercheList, ';');




    if sRechercheList.Count = 0 then begin
       sRechercheList.Free;
       exit;
    end;

    sRechercheListAllies := TStringList.Create;
    sfcStrListTokensCollect(txtAllies.Text, sRechercheListAllies, ';');


    GalaxyTriee := TCollectionGalaxyTriee.Create;


    sAdd := '';
    for i := sRechercheList.Count - 1 downto 0 do begin
       sRechercheList.Strings[i] := lowercase(trim(sRechercheList.Strings[i]));

       if sRechercheList.Strings[i] = '' then begin
          sRechercheList.Delete(i);
          Continue;
       end;

       if sAdd = '' then
          sAdd := sRechercheList.Strings[i]
       else
          sAdd := sAdd + ', ' + sRechercheList.Strings[i];

    end;

    if sRechercheListAllies.Count > 0 then begin
       for i := sRechercheListAllies.Count - 1 downto 0 do begin
          sRechercheListAllies.Strings[i] := lowercase(trim(sRechercheListAllies.Strings[i]));

          if sRechercheListAllies.Strings[i] = '' then begin
             sRechercheListAllies.Delete(i);
          end;

       end;
    end;


    AfficheMsgGalaxy('');
    AfficheMsgGalaxy('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
    AfficheMsgGalaxy('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
    AfficheMsgGalaxy(format(_('# Recherche alliances: %s'), [sAdd]));
    AfficheMsgGalaxy('');


    AfficheMsgGalaxy(format(_('Validité: %s'), [DateTimeToStr(Now)]));
    AfficheMsgGalaxy('');

    if chkPlaneteHTMLResultat.Checked then begin
       AfficheMsgGalaxy('<table class=coordls><tr><th>Coord</th><th>Alliance</th><th>Joueur</th><th>Stats</th><th>Flotte</th></tr>')
    end;


    GalaxyTriee.Import(FBase2DonneesPlanete);


    for i := 0 to GalaxyTriee.Count - 1 do begin
        pe := GalaxyTriee.Items[i];

        j := sRechercheList.IndexOf(lowercase(pe.Alliance));

        bAllies := false;
        if (j < 0) and (sRechercheListAllies.Count > 0) then begin

            j := sRechercheListAllies.IndexOf(lowercase(pe.Alliance));
            if j >= 0 then
               bAllies := true;
        end;


        if j >= 0 then begin

           sAdd := mbtPlanetLocationToStr(pe.Location);
           if chkPlaneteHTMLResultat.Checked then begin
              sHTML := '<tr><td>' + sAdd + '</td><td>' + pe.Alliance + '</td><td>' + pe.Joueur + '</td><td>';

           end else if chkHTMLText.Checked then begin
              if pe.Lune.Surface > 0 then begin
                 sAdd := '<font class=lune>' + sAdd + '</font>';
              end;

              sHTML := '<tr><td>' + sAdd;
              if pe.Location.Position < 10 then begin
                 sHTML := sHTML + '&nbsp;';
              end;

              sHTML := sHTML + '</td><td class=cally>';
           end;

           if pe.Location.Position < 10 then begin
              sAdd := sAdd + ' ';
           end;

           if pe.Lune.Surface > 0 then begin
              sAdd := sAdd + ' [Lune]';

              if chkHTMLText.Checked then begin
                 //sHTML := sHTML + ' <font class=lune>[Lune]</font>';
              end;
           end;

           sAdd := sAdd + ' - ' + pe.Joueur + ' [' + pe.Alliance + '] -- ';

           if chkHTMLText.Checked then begin
              if bAllies then
                 sAdd := '<font class=al>'
              else
                 sAdd := '<font class=en>';

              sHTML := sHTML + sAdd + pe.Alliance + '</font></td><td>' + pe.Joueur + '</td>';
           end;

           pStats := FCurrentPlayer.StatsPlayer.Get_Pointeur(pe.Joueur);

           if pStats = nil then begin
              sAdd := sAdd + 'Non classé';
              if chkPlaneteHTMLResultat.Checked then
                 sHTML := sHTML + '-</td><td>';
              if chkHTMLText.Checked then begin
                 sHTML := sHTML + '<td class=nc>Non classé';
              end;

           end else begin
              sTmp := sfcFormatStrToMilliersPX(pStats.Points);
              sAdd := sAdd + sTmp + ' points (' + IntToStr(pStats.Place) + 'eme)';

              if chkPlaneteHTMLResultat.Checked then
                 sHTML := sHTML + sTmp + ' (' + IntToStr(pStats.Place) + 'eme)</td><td>';
              if chkHTMLText.Checked then begin
                 k := pStats.Place div 100;
                 Inc(k);


                 sHTML := sHTML + format('<td class=ct%d>', [k]) + sTmp + ' (' + IntToStr(pStats.Place) + 'eme)';
              end;

           end;

           if chkHTMLText.Checked then begin
              sHTML := sHTML + '</td><td>';
           end;

           sAdd := sAdd + ' -- Flotte: ';

           pStats := FCurrentPlayer.StatsPlayerFlottes.Get_Pointeur(pe.Joueur);
           if pStats = nil then begin
              sAdd := sAdd + 'Non classé';
              if chkPlaneteHTMLResultat.Checked then
                 sHTML := sHTML + '-</td>';
              if chkHTMLText.Checked then begin
                 sHTML := sHTML + ' <font class=nc>Non classé</font>';
              end;

           end else begin
              sTmp := sfcFormatStrToMilliersPX(pStats.Points);
              sAdd := sAdd + sTmp + ' points (' + IntToStr(pStats.Place) + 'eme)';
              if chkPlaneteHTMLResultat.Checked then
                 sHTML := sHTML + sTmp + ' (' + IntToStr(pStats.Place) + 'eme)</td>';
              if chkHTMLText.Checked then begin
                 sHTML := sHTML + sTmp + ' (' + IntToStr(pStats.Place) + 'eme)';
              end;

           end;
(*
           sAdd := sAdd + ' -- Recherche: ';

           pStats := FStatsPlayerRecherche.Get_Pointeur(pe.Joueur);
           if pStats = nil then begin
              sAdd := sAdd + 'Non classé';
           end else
              sAdd := sAdd + IntToStr(pStats.Points) + ' (' + IntToStr(pStats.Place) + 'ieme)';
*)
           if chkPlaneteHTMLResultat.Checked then begin
              AfficheMsgGalaxy(sHTML + '</tr>');
           end else if chkHTMLText.Checked then begin
              AfficheMsgGalaxy(sHTML + '</td></tr>');
           end else begin
              AfficheMsgGalaxy(sAdd);
           end;

        end;

    end;

    
    if chkPlaneteHTMLResultat.Checked then begin
       AfficheMsgGalaxy('</table>')
    end;

    sRechercheList.Free;
    sRechercheListAllies.Free;
    GalaxyTriee.Free;

end;

procedure TfrmRapportHistorique.cmdRessourceCalculerClick(Sender: TObject);
begin
    EnableOrDisableWebActionButton(false);

    // on change la planète sur le site
    if FCurrentPlayer.ChangePlanete(FCurrPlayerCurrPlanetForConstruction.FLocation) < 0 then begin
       // Inutile de continuer
       Status(_('Erreur lors du changement de planète'));
       EnableOrDisableWebActionButton(true);
       exit;
    end;



    //try
       FCurrentPlayer.ProceedUpdateRessource(true, true);

       LoadPlanetInForm(FCurrentPlayer.curPlanete);

       FCurrPlayerCurrPlanete               := FCurrentPlayer.curPlanete;
       FCurrPlayerCurrPlanetForConstruction := FCurrPlayerCurrPlanete;

    //finally
       EnableOrDisableWebActionButton(true);
    //end;
end;

procedure TfrmRapportHistorique.cmdRessourcesUpdateClick(Sender: TObject);
begin
    EnableOrDisableWebActionButton(false);

    // on change la planète sur le site
    if FCurrentPlayer.ChangePlanete(FCurrPlayerCurrPlanetForConstruction.FLocation) < 0 then begin
       // Inutile de continuer
       Status(_('Erreur lors du changement de planète'));
       EnableOrDisableWebActionButton(true);
       exit;
    end;



    //try
       FCurrentPlayer.ProceedUpdateRessource(true, false);

       LoadPlanetInForm(FCurrentPlayer.curPlanete);

       FCurrPlayerCurrPlanete               := FCurrentPlayer.curPlanete;
       FCurrPlayerCurrPlanetForConstruction := FCurrPlayerCurrPlanete;

    //finally
       EnableOrDisableWebActionButton(true);
    //end;

end;

procedure TfrmRapportHistorique.CaptureClipboardActivation;
begin
    FLastClipboard := 'ab';
    Clipboard.AsText := FLastClipboard;
    timMonitorClipboard.Interval := 500;
    cmdClipboardSwitch.Caption := _('Clipboard - DésActiver');

    menCaptureRapportDesactiver.Checked := false;
    menCaptureRapportActiver.Checked    := true;
end;

procedure TfrmRapportHistorique.CaptureClipboardDesactivation;
begin
    timMonitorClipboard.Interval := 0;
    cmdClipboardSwitch.Caption := _('Clipboard - Activer');

    menCaptureRapportDesactiver.Checked := true;
    menCaptureRapportActiver.Checked := false;
end;

procedure TfrmRapportHistorique.cmdClipboardSwitchClick(Sender: TObject);
begin

    if timMonitorClipboard.Interval = 0 then begin
       CaptureClipboardActivation

    end else begin
       CaptureClipboardDesactivation;
    end;

end;


procedure TfrmRapportHistorique.menCaptureRapportActiverClick(Sender: TObject);
begin
     CaptureClipboardActivation;
end;

procedure TfrmRapportHistorique.menCaptureRapportDesactiverClick(
  Sender: TObject);
begin
    CaptureClipboardDesactivation;
end;

procedure TfrmRapportHistorique.SaveProfilIfIsValid;
begin
    // sauvegarde l'ancien profil
    if FCurrentPlayer.Conf.IsValidProfil then begin
       FCurrentPlayer.Conf.SaveToFile('');

       if FCurrentPlayer.allPlanetes.Count > 0 then begin
          FCurrentPlayer.SaveToFile('');
       end;

       Status(format(_('Ancien profil %s sauvegardé.'), [FCurrentPlayer.Conf.Pseudo]));
    end;

end;

procedure TfrmRapportHistorique.menChangerdeprofil1Click(Sender: TObject);
begin
   // on doit changer de profil
   SaveProfilIfIsValid;


       if formProfilChoix = nil then begin
          formProfilChoix := TformProfilChoix.Create(Self);
       end;

       formProfilChoix.PrepareToShow(true);


       formProfilChoix.ShowModal;

       if formProfilChoix.ProfilToLoad = '' then begin
          // aucun profil à charger

       end else begin
          LoadProfilFullPath(formProfilChoix.ProfilToLoad);

       end;

       
       formProfilChoix.Free;
       formProfilChoix := nil;
end;

procedure TfrmRapportHistorique.AfficheResultatOptimization(r: TResultatBestProd);
var i: integer;
begin

   for i := 0 to MAX_RES_OG do begin
       Status(IntToStr(i) + ' -> ' + IntToStr(r[i]));

   end;
end;

procedure TfrmRapportHistorique.menConstructionVoirOptimisationClick(
  Sender: TObject);
var i, k: integer;
    cE: POGItemCost;
    lProduction: TList;
    TempRestante: integer;
    xResultat: TResultatBestProd;

    pxOpt: POGResUsed;
begin
    if FLastLigneSelectedInConstruction < 0 then begin
       exit;
    end;

    // Ajoute l'élément dans l'action manager
    if FLastLigneSelectedInConstruction > 0 then begin
       // les deux premières lignes correspondant aux ressources et à la production
       i := FLastLigneSelectedInConstruction - 3;

       if i >= FCurrPlayerCurrPlanetForConstruction.cElements.Count then exit;
       if i < 0 then begin
          exit;
       end;

       cE := FCurrPlayerCurrPlanetForConstruction.cElements.Items[i];

       k := GetTypeOfGID(cE.GID);

       if (k <> CNT_ITEM_DESIGN_BATIMENT) and (k <> CNT_ITEM_DESIGN_RECHERCHE) then begin
          // non géré
          exit;
       end;

       if cE.CanBeBuildIn <= 0  then begin
          // déjà constructible
          // ou
          // impossible à optimiser
          exit;
       end;

       
       lProduction := TList.Create;

       //DupliqueTList(FCurrPlayerCurrPlanetForConstruction.cRessources, lProduction);

       FCurrPlayerCurrPlanetForConstruction.cRessources.DupliqueTo(lProduction);


       GetRessourceWithBestEstimationOfActivity100(lProduction);

       xResultat := GetBestActivityProduct(cE.Prix, lProduction, TempRestante);

       lProduction.Free;

       
       for i := 0 to MAX_RES_OG do begin
           if i >= FCurrPlayerCurrPlanetForConstruction.cRessources.Count then begin
              break;
           end;
           pxOpt := FCurrPlayerCurrPlanetForConstruction.cRessources.Items[i];
           pxOpt.ActiviteForOptimization := xResultat[i];
       end;

       // Ressources
       AfficheResRowInGrid(sgRessourcesProd, FCurrPlayerCurrPlanetForConstruction.cRessources, FCurrPlayerCurrPlanetForConstruction.FLastRessources, true);

       pcConstruction.ActivePageIndex := tabConstructionRessources.PageIndex;
    end;
end;

procedure TfrmRapportHistorique.menDureeRecent1hClick(Sender: TObject);
begin
    seDureeForRecent.Value := 3600;
    cmdAppliqueAnciennetesClick(nil);
end;

procedure TfrmRapportHistorique.menDureeRecent2hClick(Sender: TObject);
begin
    seDureeForRecent.Value := 3600 * 2;
    cmdAppliqueAnciennetesClick(nil);
end;

procedure TfrmRapportHistorique.menDureeRecent3hClick(Sender: TObject);
begin
    seDureeForRecent.Value := 3600 * 3;
    cmdAppliqueAnciennetesClick(nil);
end;

procedure TfrmRapportHistorique.menDureeRecent5hClick(Sender: TObject);
begin
    seDureeForRecent.Value := 3600 * 5;
    cmdAppliqueAnciennetesClick(nil);
end;

procedure TfrmRapportHistorique.menDureeRecent10hClick(Sender: TObject);
begin
    seDureeForRecent.Value := 3600 * 10;
    cmdAppliqueAnciennetesClick(nil);
end;

procedure TfrmRapportHistorique.menDureeRecent1jClick(Sender: TObject);
begin
    seDureeForRecent.Value := 3600 * 24;
    cmdAppliqueAnciennetesClick(nil);
end;

procedure TfrmRapportHistorique.menDureeRecent2jClick(Sender: TObject);
begin
    seDureeForRecent.Value := 3600 * 24 * 2;
    cmdAppliqueAnciennetesClick(nil);
end;


function TfrmRapportHistorique.AppTerminating: boolean;
var r: integer;
begin

    if FCurrentPlayer.Conf.IsValidProfil then begin
       FCurrentPlayer.Conf.SaveToFile('');

       if FCurrentPlayer.allPlanetes.Count > 0 then begin
          FCurrentPlayer.SaveToFile('');
       end;
    end;

    
    if FBase2DonneesRapports.ExistSomeDataToSave then begin
       r := Application.MessageBox('La base de données n''a pas été sauvegardé, voulez vous continuer ?', 'Remarque', MB_YESNOCANCEL + MB_ICONQUESTION);

       if r <> ID_YES then begin
          // L'utilisateur à choisit Non ou Annuler
          exit;

       end;

    end;

    Result := true;
end;

procedure TfrmRapportHistorique.Quitter1Click(Sender: TObject);
var CanClose: boolean;
begin

    CanClose := true;


    FormCloseQuery(Self, CanClose);



    if NoT(CanClose) then begin
       // on ne quitte plus
       exit;
    end;

    StopTimers;

    // Quitte
    Application.Terminate;
end;

procedure TfrmRapportHistorique.seSystemSolairChoixChange(Sender: TObject);
begin
     // Charge le système choisit
     LoadAndUpdateSystemSolaire(seSystemSolairChoix.Value);

end;

procedure TfrmRapportHistorique.menSpiderLoginClick(Sender: TObject);
begin
    SpiderDoLogin;
end;

procedure TfrmRapportHistorique.SpiderGalaxieSetToScan(Galaxie: integer);
var FichierGalaxie: string;
begin


    // Obtient le fichier de la galaxie dès maintenant
    FichierGalaxie := GetFileFromScanForThisGalaxie(FCurrentPlayer.Conf.Univers, Galaxie, tbdGalaxie);

    if FichierGalaxie <> '' then begin
       txtSpiderGalaxieScanFile.Text := ExtractFileName(FichierGalaxie);
       txtSpiderGalaxieScanFile.Font.Color := clBlue;

    end else begin
       txtSpiderGalaxieScanFile.Text := format(CNT_GALAXIE_DB_FILE_FORMAT, [FCurrentPlayer.Conf.Univers, Galaxie]);
       txtSpiderGalaxieScanFile.Font.Color := clBlack;
    end;

end;

procedure TfrmRapportHistorique.cmdSpiderGalaxieStopClick(Sender: TObject);
begin
     chkSonderEnsuiteLesInactifs.Checked := false;
     FCurrentPlayer.ProcRecolteArret := true;
end;

procedure TfrmRapportHistorique.cmdSpiderStatsStopClick(Sender: TObject);
begin
     FCurrentPlayer.ProcRecolteArret := true;
end;

function TfrmRapportHistorique.GetStatsUniPath: string;
begin
    Result := FDossierStats + format('u%2.2d\', [FCurrentPlayer.Conf.Univers]);
end;


procedure TfrmRapportHistorique.cmdSpiderStatsScanClick(Sender: TObject);
label lblEnd;
var StatsAll: TCollectionPlayerStats;
    sType : string;
    sDateShort: string;
    DossierStatsUni: string;
    iNbCond: integer;
begin


    cmdSpiderStatsScan.Enabled := false;
    cmdSpiderGalaxieScan.Enabled := false;


    DossierStatsUni := GetStatsUniPath;
    ForceDirectories(DossierStatsUni);


    // Obtient les anciens fichiers au cas où l'on ne met pas à jour
    // toutes les stats
    if FStatsGetFileRecent.GetFromDir(DossierStatsUni) then begin
       // toutes les conditions sont déjà remplies
       iNbCond := 3;
    end;

    Status('Récolte des statistiques, dossier: ' + DossierStatsUni);


    StatsAll := TCollectionPlayerStats.Create;
    StatsAll.DebugProc := Status;
    StatsAll.Capacity := 1502;

    StatsAll.Univers := FCurrentPlayer.Conf.Univers;
    StatsAll.DateCreation := DateTimeToUnix(Now);


    if chkSpiderStatsDateUnixAbrege.Checked then begin
       // 20051003
       sDateShort := ESBGetDateForFormatFile(Now) + '-' + format('%2.2d%2.2d', [HourOf(Now), MinuteOf(Now)]);

    end else
       sDateShort := IntToStr(StatsAll.DateCreation shr 4);


    if chkSpiderStatsGlobales.Checked then begin
       Status(_('-> Globales'));
       StatsAll.TypeStats := STATS_TYPE_ALL;



       if FCurrentPlayer.ProceedCollectStatsPlayer(StatsAll, stoPoints) <= 0 then begin
          Status(_('Erreur téléchargement'));
       end;
       if FCurrentPlayer.ProcRecolteArret then begin
          Status(_('Arrêt de la récolte (Interrompu par l''utilisateur)'));
          goto lblEnd;
       end;


       sType := 'a';

       if StatsAll.Count < 1000 then begin
           Status(format(_('Statistiques non récupérées entièrement (Elements: %d)'), [StatsAll.Count]));


          // Pas assez d'élément pour creer le fichier
          // peut-être que c'est un début d'univers ?

       end else  begin
          FStatsGetFileRecent.FileStatsAll := DossierStatsUni + format('so%s_%d%s.txt', [sDateShort, StatsAll.Univers, sType]);
          StatsAll.SaveToFile(FStatsGetFileRecent.FileStatsAll);
          Inc(iNbCond);
       end;

       Sleep(100);
       Application.ProcessMessages;
       Sleep(100);
       Application.ProcessMessages;
       Sleep(100);
    end;

    StatsAll.Clear;



    if chkSpiderStatsFlottes.Checked then begin
       Status(_('-> Flotte'));
       StatsAll.TypeStats := STATS_TYPE_FLOTTES;
       if FCurrentPlayer.ProceedCollectStatsPlayer(StatsAll, stoFlottes)  <= 0 then begin
          Status(_('Erreur téléchargement'));
       end;
       if FCurrentPlayer.ProcRecolteArret then begin
          Status(_('Arrêt de la récolte (Interrompu par l''utilisateur)'));
          goto lblEnd;
       end;

       sType := 'f';

       if StatsAll.Count < 1000 then begin
           Status('Statistiques non récupérées entièrement (Elements: ' + IntToStr(StatsAll.Count) + ')');
          // Pas assez d'élément pour creer le fichier

       end else  begin
          FStatsGetFileRecent.FileStatsFlottes := DossierStatsUni + format('so%s_%d%s.txt', [sDateShort, StatsAll.Univers, sType]);
          StatsAll.SaveToFile(FStatsGetFileRecent.FileStatsFlottes);
          Inc(iNbCond);
       end;

       Sleep(100);
       Application.ProcessMessages;
       Sleep(100);
       Application.ProcessMessages;
       Sleep(100);
    end;

    StatsAll.Clear;



    if chkSpiderStatsRecherche.Checked then begin
       Status(_('-> Recherche'));
       StatsAll.TypeStats := STATS_TYPE_RECHERCHE;
       if FCurrentPlayer.ProceedCollectStatsPlayer(StatsAll, stoRecherche) <= 0 then begin
          Status(_('Erreur téléchargement'));
       end;
       if FCurrentPlayer.ProcRecolteArret then begin
          Status(_('Arrêt de la récolte (Interrompu par l''utilisateur)'));
          goto lblEnd;
       end;

       sType := 'r';

       if StatsAll.Count < 1000 then begin
           Status('Statistiques non récupérées entièrement (Elements: ' + IntToStr(StatsAll.Count) + ')');
          // Pas assez d'élément pour creer le fichier

       end else  begin
          FStatsGetFileRecent.FileStatsRecherche := DossierStatsUni + format('so%s_%d%s.txt', [sDateShort, StatsAll.Univers, sType]);
          StatsAll.SaveToFile(FStatsGetFileRecent.FileStatsRecherche);
          Inc(iNbCond);
       end;

    end;

    FStatsGetFileRecent.SetToDir(DossierStatsUni);


    Status(_('Terminé'));
    LoadStatsFileForUnivers(FCurrentPlayer.Conf.Univers, iNbCond >= 3);


lblEnd:
    StatsAll.Free;
    cmdSpiderStatsScan.Enabled := true;
    cmdSpiderGalaxieScan.Enabled := true;

end;

procedure TfrmRapportHistorique.menGalaxieSetRangeScanClick(Sender: TObject);
var x: TMenuItem;
begin
    x := TMenuItem(Sender);
    SpiderGalaxieSetRangeFromCurrent(x.Tag);
end;


procedure TfrmRapportHistorique.menLADescendreClick(Sender: TObject);
begin
   if (FCurrentIndiceListAttackSel < 0) then begin
      exit;
   end;

   if (FCurrentIndiceListAttackSel >= FCurrentPlayer.cListeDattaque.Count) then begin
      exit;
   end;
   if (FCurrentPlayer.cListeDattaque.Count = 1) or (FCurrentIndiceListAttackSel = FCurrentPlayer.cListeDattaque.Count - 1) then begin
      // un seul élément ou il est deja en bas de liste
      exit;
   end;

   FCurrentPlayer.cListeDattaque.Exchange(FCurrentIndiceListAttackSel, FCurrentIndiceListAttackSel + 1);

   FCurrentIndiceListAttackSel := -1;
   cmdListeAttaqueUpdateListClick(nil);

end;

procedure TfrmRapportHistorique.menLAEnleverClick(Sender: TObject);
begin

   if (FCurrentIndiceListAttackSel < 0) then begin
      exit;
   end;

   if (FCurrentIndiceListAttackSel >= FCurrentPlayer.cListeDattaque.Count) then begin
      exit;
   end;

   FCurrentPlayer.cListeDattaque.Delete(FCurrentIndiceListAttackSel);
   FCurrentIndiceListAttackSel := -1;

   cmdListeAttaqueUpdateListClick(nil);

   
end;

procedure TfrmRapportHistorique.menLAMonterClick(Sender: TObject);
begin
   if (FCurrentIndiceListAttackSel < 0) then begin
      exit;
   end;

   if (FCurrentIndiceListAttackSel >= FCurrentPlayer.cListeDattaque.Count) then begin
      exit;
   end;
   if (FCurrentPlayer.cListeDattaque.Count = 1) or (FCurrentIndiceListAttackSel = 0) then begin
      // un seul élément ou il est deja en haut de liste
      exit;
   end;

   FCurrentPlayer.cListeDattaque.Exchange(FCurrentIndiceListAttackSel, FCurrentIndiceListAttackSel - 1);

   FCurrentIndiceListAttackSel := -1;
   cmdListeAttaqueUpdateListClick(nil);

end;

function myGetFileSize(const APath: string): int64;
var
  Sr : TSearchRec;
begin

  if FindFirst(APath, faAnyFile, Sr) = 0 then begin
     try
       Result := Int64(Sr.FindData.nFileSizeHigh) shl 32 + Sr.FindData.nFileSizeLow;
     finally
       FindClose(Sr);
     end;

  end else begin
    Result := 0;

  end;
end;

procedure TfrmRapportHistorique.cmdSpiderGalaxieScanClick(Sender: TObject);
label lStart, lEnd;
var DeutRequis: integer;
    NbSystem, x: integer;
    FichierDst: string;

    cBase2Donnees: TCollectionGalaxiePlanete;
    cHaveToFree: boolean;
    DateWitchNeedntToBeUpdated: int64;
    bFichierCree: boolean;
    xDateStart: int64;
    lSecu: integer;
begin


     cmdSpiderGalaxieScan.Enabled := false;
     cmdSpiderStatsScan.Enabled := false;

     if chkScanFullUnivers.Checked then begin
        // scan depuis le début
        seGalaxieSystemeStart.Value := 1;
        seGalaxieSystemeEnd.Value   := FCurrentPlayer.Conf.UniversNbSystemSolaireParGalaxy;
     end;

lStart:

       if FInfosBaseDeDonneCharge = false then begin
          // aucune base de données chargées...
          Status(_('Aucune base de données chargée'));
          goto lEnd;
       end;

     xDateStart := DateTimeToUnix(Now);

     // se déplace sur la bonne planète
     if SpiderChangePlaneteToGalaxieScanSelected < 1 then begin
        Status(_('Echec de changement de planète'));
        goto lEnd;
     end;

     Status('Deutérium disponible: ' + IntToStr(FCurrentPlayer.curLastHeader.CurrRessource.Deuterium));


     if seGalaxieSystemeStart.Value > seGalaxieSystemeEnd.Value then begin
         NbSystem := seGalaxieSystemeStart.Value - seGalaxieSystemeEnd.Value + 1;
     end else begin
         NbSystem := seGalaxieSystemeEnd.Value - seGalaxieSystemeStart.Value + 1;
     end;

     DeutRequis := NbSystem * 10;

     if FCurrentPlayer.curLastHeader.CurrRessource.Deuterium < DeutRequis + 20 then begin
        // pas assez de deuterium
        Status(_('Pas assez de deuterium pour tout parcourrir'));
        goto lEnd;
     end;

     seSondageIgnoreDelayLastSondage.Value := 10;

     FichierDst := FDossierGalaxieDB + txtSpiderGalaxieScanFile.Text;


     cHaveToFree := true;
     bFichierCree := false;


     if FBase2DonneesPlanete.FichierSave <> '' then begin
        if SameText(FBase2DonneesPlanete.FichierSave, FichierDst) then begin
           // mise à jour de la base de données actuelle
           Status('Le fichier actuellement chargé correspond à celui que l''on va mettre à jour');
           Status('Vérification du numéro de galaxie et d''univers');


           if FBase2DonneesPlanete.Univers <> FCurrentPlayer.Conf.Univers then begin
              // Sérieux problème
              Status(format('L''univers ne correspond pas (Fichier: %d, Profil: %d)', [FBase2DonneesPlanete.Univers, FCurrentPlayer.Conf.Univers]));
              goto lEnd;
           end;

           if FBase2DonneesPlanete.Galaxie = seDBGalaxie.Value then begin
              cBase2Donnees := FBase2DonneesPlanete;
              cHaveToFree := false;
           end else begin
              // La galaxie ne correspond pas
              Status(format('La galaxie ne correspond pas (Fichier: %d, Current: %d)', [FBase2DonneesPlanete.Galaxie, seDBGalaxie.Value]));
              goto lEnd;
           end;

           
        end else begin
           Status(_('Le fichier actuellement chargé NE correspond PAS à celui que l''on va mettre à jour'));
        end;

        // sinon ceux sont des noms de fichier différent
     end;
     




     if cHaveToFree then begin
        cBase2Donnees := TCollectionGalaxiePlanete.Create;

        Status(format(_('Chargement du fichier: %s'), [FichierDst]));

        if cBase2Donnees.LoadFromFile(FichierDst) < 0 then begin
           // Le fichier n'existe pas
           Status(_('Fichier inexistant, il sera créé'));
           cBase2Donnees.Univers := FCurrentPlayer.Conf.Univers;
           cBase2Donnees.Galaxie := seDBGalaxie.Value;
           bFichierCree := true;

        end else begin
           Status(_('Fichier déjà existant - Vérification du numéro de galaxie et d''univers'));

           if (cBase2Donnees.Univers <> FCurrentPlayer.Conf.Univers) then begin
              Status(_('L''univers ne correspond pas avec celui que l''on va scanner'));
              cBase2Donnees.Free;
              goto lEnd;

           end else if (cBase2Donnees.Galaxie <> seDBGalaxie.Value) then begin
              Status(_('La galaxie ne correspond pas avec celle que l''on va scanner'));
              cBase2Donnees.Free;
              goto lEnd;
           end;

        end;

     end;


     cmdSpiderGalaxieScan.Enabled := false;


     DateWitchNeedntToBeUpdated := DateTimeToUnix(Now) - seSpiderGalaxieDureeRecent.Value;

     Status('Date limite de mise à jour: ' + DateTimeToStr(UnixToDateTime(DateWitchNeedntToBeUpdated)));



     Status(_('Début du scan'));

     if FCurrentPlayer.ProceedGalaxieScan(cBase2Donnees, seDBGalaxie.Value, seGalaxieSystemeStart.Value, seGalaxieSystemeEnd.Value, DateWitchNeedntToBeUpdated) <= 0 then begin

        if FCurrentPlayer.ProcRecolteArret then begin
           Status(_('Arrêt du parcours de la galaxie (Interrompu par l''utilisateur)'));
           chkScanFullUnivers.Checked := false;
        end else begin
           formConfirmation.ShowNotifErreur(_('Erreur'));
           Status(_('Echec du scanner'));
        end;

     end else begin
        Status(_('Téléchargement terminé.'));
     end;

     OnObjectEnter(Sender);

     NbSystem := cBase2Donnees.SaveToFile('');

     
     Status(format(_('Sauvegarde terminé (%d éléments sauvegardés)'), [NbSystem]));


     if cHaveToFree then begin
        cBase2Donnees.Free;
     end;

     if bFichierCree then begin
        // le fichier a été créé, donc normalement cHaveToFree devait être à True
        // On charge maintenant le fichier
        FBase2DonneesPlanete.LoadFromFile(FichierDst);
     end;




     if chkScanFullUnivers.Checked then begin
        if seDBGalaxie.Value < FCurrentPlayer.Conf.UniversNbGalaxy then begin
           seDBGalaxie.Value := seDBGalaxie.Value + 1;

           seDBGalaxieChange(nil);

           // la charge
           if cmdLoadDBFromProfils.Enabled  then begin
              cmdLoadDBFromProfilsClick(nil);

              // et scan à nouveau
              goto lStart;
           end;



        end;
     end;


     FChampDeRuineList.Clear;
     //FChampDeRuineList.ImportChampDeRuine(FBase2DonneesPlanete, xDateStart - 5);
     FChampDeRuineList.ImportChampDeRuine(FBase2DonneesPlanete, DateTimeToUnix(Now) - seDureeForRecent.Value);

     // mets tout à jour
     UpdateAll;




     cmdSpiderGalaxieScan.Enabled := true;

     if chkSonderEnsuiteLesInactifs.Checked then begin
        // Ajoute les inactifs
        cmdSondageInactifsClick(nil);

        // Démarre les sondages
        cmdSondageStartClick(nil);

     end else
        formConfirmation.ShowNotif(_('Terminé'));


lEnd:
    cmdSpiderGalaxieScan.Enabled := true;
    cmdSpiderStatsScan.Enabled := true;
end;


function TfrmRapportHistorique.SondageCheckAndTryToAddThisCoord(Coord: TPlanetLocation; peGalaxie: PGalaxiePlanete; OverrideRapportFlags: boolean): boolean;
var peRapport: PRapportHead;
    Duree, LastAttack: int64;
    peSondage: PPlaneteASonder;
    TotalRessource: integer;
    NbPT: integer;
begin


         Result := false;

         // Coordonnées à sonder,
         // MAIS cependant, elle doit être sondable, c'est à dire
         // que le joueur ne doit pas être en mode vacances
         // Ou encore ne pas être un allié
         // Ou qu'il n'a pas été sondé il y a quelques dizaine de minutes
         // et gère aussi le nombre de sondes si la planète a déjà été sondé

         if (sfcFlagsIsIn(CNT_GALAXIE_FLAGS_MODE_VACANCES, peGalaxie.Flags)) or
            (sfcFlagsIsIn(CNT_GALAXIE_FLAGS_PROTECTION_NOOB_TROPFAIBLE, peGalaxie.Flags)) or
            (sfcFlagsIsIn(CNT_GALAXIE_FLAGS_PROTECTION_NOOB_TROPFORT, peGalaxie.Flags)) or
            (sfcFlagsIsIn(CNT_GALAXIE_FLAGS_PLANETE_NON_OCCUPEE, peGalaxie.Flags))or
            (sfcFlagsIsIn(CNT_GALAXIE_FLAGS_ASTEROIDES, peGalaxie.Flags)) then begin


            // Impossible à scanner
            if chkSondageMsgDebug.Checked then
               Status('Sondage - Impossible ' + mbtPlanetLocationToStr(peGalaxie.Location) + ' car flags: ' + gpGetFlagsStrToFullUsage(peGalaxie.Flags));

         end else begin



            if (chkSonderLesAllies.Checked = false) and FCurrentPlayer.Conf.IsAllianceAlliees(peGalaxie.Alliance) then begin
               // On ne le sonde pas
               Status('Sondage - Non ajouté car alliance alliée: ' +  mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']');

            end else if FCurrentPlayer.Conf.IsPlayerAllies(peGalaxie.Joueur) then begin
               Status('Sondage - Non ajouté car c''est une de nos planètes: ' +  mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']');


            end else begin
               //////////////////////////////////////
               // Vérifie la date de dernier sondage:

               peRapport := FBase2DonneesRapports.Get_Pointeur(Coord);

               if peRapport <> nil then begin
                  Duree := FCurrDate - mrGetMostRecentDate(peRapport.DateLastEspionnage);

                  if chkSondageDoDateVerifForRapportToo.Checked then begin
                     if Duree > seSondageDureePourEtrePrisEnCompte.Value then begin
                        // Rapport trop ancien
                        Status('Sondage - Non ajouté car rapport d''espionnage trop ancien: ' +  mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + '] ' + ESBDGetDureeStrings(Duree, true));
                        exit;
                     end;
                  end;

                  if sfcFlagsIsIn(FLAG_NE_JAMAIS_ATTACK, peRapport.Flags) then begin
                     // ne dois jamais être attaqué (et ni sondé donc)
                     if chkSondageMsgDebug.Checked or OverrideRapportFlags then
                        Status('Sondage - Non ajouté car flag NE_JAMAIS_ATTACK: ' +  mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']');
                     exit;
                  end;

                  if sfcFlagsIsIn(FLAG_TROP_BIEN_DEF, peRapport.Flags) then begin
                     // ne dois jamais être attaqué (et ni sondé donc)
                     if chkSondageMsgDebug.Checked or OverrideRapportFlags then
                         Status('Sondage - Non ajouté car flag FLAG_TROP_BIEN_DEF: ' +  mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']');
                     exit;
                  end;

                  if sfcFlagsIsIn(FLAG_A_RECYCLER, peRapport.Flags) then begin
                     // doit être recycler prochainement, l'inclure dans un sondage
                     // de masse éveillerait les soupçons
                     if chkSondageMsgDebug.Checked or OverrideRapportFlags then
                         Status('Sondage - Non ajouté car flag FLAG_A_RECYCLER: ' +  mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']');
                     exit;
                  end;


                  if chkDontSondeDejaRecycler.Checked then begin
                     if sfcFlagsIsIn(FLAG_DEJA_RECYCLER, peRapport.Flags) then begin
                        if chkSondageMsgDebug.Checked or OverrideRapportFlags then
                           Status('Sondage - Non ajouté car chkDontSondeDejaRecycler et flag FLAG_DEJA_RECYCLER: ' +  mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']');
                        exit;

                     end;

                  end;



                  if OverrideRapportFlags = false then begin

                     if chkAddOnlyKnowEtSansDef.Checked then begin
                        // vérifie qu'il n'a aucune défense
                        if (scDefense in peRapport.SectionConnu) then begin
                           if (peRapport.DefenseScore <> 0) then begin
                              // il existe de la défense (ou inconnu si négatif)
                              Status('Sondage - Non ajouté car possède de la défense - chkAddOnlyKnowEtSansDef');
                              exit;
                           end;

                           // si la défense est connue, la flotte aussi
                           if peRapport.RecyclageNbRessource > 0 then begin
                              // il y a de la flotte (à recycler) donc des vaisseaux
                              Status('Sondage - Non ajouté car possède de la flotte - chkAddOnlyKnowEtSansDef');
                              exit;
                           end;

                        end else begin
                            //  défense inconnu
                            Status('Sondage - Non ajouté car défense inconnue - chkAddOnlyKnowEtSansDef');
                            exit;
                        end;

                     end;

                     if sfcFlagsIsIn(FLAG_MODE_TROP_PEUDEV, peRapport.Flags) then begin
                        if Duree < FCurrentPlayer.Conf.NewbzDelaisIngoreSondage then begin
                           if chkSondageMsgDebug.Checked then
                              Status('Sondage - Non ajouté car flag TROP_PEUDEV et la durée d''attente n''a pas encore été atteinte: ' +  mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']  Durée: ' + IntToStr(Duree) + ' sur ' + IntToStr(FCurrentPlayer.Conf.NewbzDelaisIngoreSondage));
                           exit;
                        end;

                     end;


                     if chkSondageMinRecycleur.Checked then begin
                        // Condition sur le nombre de recycleur mini si déjà sondé
                        NbPT := Ceil(peRapport.RecyclageNbRessource div 20000);

                        if NbPT < seSondageMinRecycleurs.Value then begin
                           // pas assez de Recycleur
                           Status('Sondage - Non ajouté car pas assez de Recycleur: ' +  mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']  Recycleur: ' + IntToStr(NbPT));
                           exit;
                        end;

                     end;

                     if chkSondageMaxDefScore.Checked then begin
                        // max defense
                        if peRapport.DefenseScore > seSondageMaxScoreDef.Value then begin
                           // trop de défense
                           Status('Sondage - Non ajouté car trop grand score de défense: ' +  mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']  Score: ' + IntToStr(peRapport.DefenseScore));
                           exit;
                        end;

                     end;

                     if chkSondageMinPT.Checked then begin
                        // Condition sur le nombre de PT mini si déjà sondé
                        TotalRessource := peRapport.Ressource.Metal + peRapport.Ressource.Cristal + peRapport.Ressource.Deuterium;
                        NbPT := Ceil((TotalRessource div 2) / 5000);

                        if NbPT < seSondageMinPT.Value then begin
                           // pas assez de PT
                           Status('Sondage - Non ajouté car pas assez de PT: ' +  mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']  PT: ' + IntToStr(NbPT));
                           exit;
                        end;

                     end;


                     if chkSondageMaxPT.Checked then begin
                        // Condition sur le nombre de PT maxi si déjà sondé
                        TotalRessource := peRapport.Ressource.Metal + peRapport.Ressource.Cristal + peRapport.Ressource.Deuterium;
                        NbPT := Ceil((TotalRessource div 2) / 5000);

                        if NbPT > seSondageMaxPT.Value then begin
                           // trop de PT
                           Status('Sondage - Non ajouté car pas trop de PT: ' +  mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']  PT: ' + IntToStr(NbPT));
                           exit;
                        end;

                     end;


                  end;

                  if chkSondageDontAddDejaAttack.Checked then begin
                     // On ajoute pas ceux qui ont déjà été attaqué
                     LastAttack := mrGetMostRecentDate(peRapport.DateLastAttaque);

                     if LastAttack > 36000 then begin
                        // déjà attaqué
                        Status('Sondage - Déjà attaqué: ' + mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']' + IntToStr(LastAttack));
                        exit;
                     end;
                  end;

                  if chkSondageDontAddDejaAttack24h.Checked then begin
                     // On ajoute pas ceux qui ont déjà été attaqué il y a moins de 24h
                     LastAttack := mrGetMostRecentDate(peRapport.DateLastAttaque);

                     if LastAttack > 36000 then begin
                        // déjà attaqué
                        LastAttack := DateTimeToUnix(Now) - LastAttack;

                        if LastAttack < 86400 then begin
                           Status('Sondage - Déjà attaqué il y a moins de 24h: ' + mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']' + IntToStr(LastAttack));
                           exit;
                        end;
                     end;
                  end;


                  if chkSondageDontAddDejaAttack12h.Checked then begin
                     // On ajoute pas ceux qui ont déjà été attaqué il y a moins de 2h
                     LastAttack := mrGetMostRecentDate(peRapport.DateLastAttaque);

                     if LastAttack > 36000 then begin
                        // déjà attaqué
                        LastAttack := DateTimeToUnix(Now) - LastAttack;

                        if LastAttack < 43200 then begin
                           Status('Sondage - Déjà attaqué il y a moins de 12h: ' + mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']' + IntToStr(LastAttack));
                           exit;
                        end;
                     end;

                  end;

                  if chkSondageDontAddDejaAttack2h.Checked then begin
                     // On ajoute pas ceux qui ont déjà été attaqué il y a moins de 2h
                     LastAttack := mrGetMostRecentDate(peRapport.DateLastAttaque);

                     if LastAttack > 36000 then begin
                        // déjà attaqué
                        LastAttack := DateTimeToUnix(Now) - LastAttack;

                        if LastAttack < 7200 then begin
                           Status('Sondage - Déjà attaqué il y a moins de 2h: ' + mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']' + IntToStr(LastAttack));
                           exit;
                        end;
                     end;

                  end;

                  if chkSondageDontSondeNivEspEleve.Checked then begin
                     if sfcFlagsIsIn(FLAG_NIV_ESP_ELEVE, peRapport.Flags) then begin
                        Status('Sondage - Niv Esp Eleve: '  + mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']');
                        exit;
                     end;
                  end;


               end else begin
                  // jamais sondé
                  Duree := seSondageIgnoreDelayLastSondage.Value + 1;

                  if chkAddOnlyKnowEtSansDef.Checked then begin
                     Status('Sondage - Non ajouté car jamais sondé - chkAddOnlyKnowEtSansDef');
                     exit;
                  end;
               end;



               if Duree < seSondageIgnoreDelayLastSondage.Value then begin
                  Status('Sondage - Sondé il y a pas longtemps: ' +  mbtPlanetLocationToStr(peGalaxie.Location));


               end else begin

                   

                  peSondage := FCurrentPlayer.SondagePlanetesList.AddIfNotExistCoord(Coord);

                  if peSondage = nil then begin
                     Status('Sondage - Déjà existant: ' +  mbtPlanetLocationToStr(peGalaxie.Location));

                  end else begin
                     if chkSondageMsgDebug.Checked then
                        Status('Sondage - Ajouté: ' +  mbtPlanetLocationToStr(peGalaxie.Location));

                     Result := true;

                     peSondage.NbSondes := FCurrentPlayer.Conf.SondesNbMini;


                     if peRapport <> nil then begin
                        if sfcFlagsIsIn(FLAG_NIV_ESP_ELEVE, peRapport.Flags) then begin
                            // Envoi plus de sondes
                            peSondage.NbSondes := FCurrentPlayer.Conf.SondesNbNivEsp;

                        end;
                     end;

                  end;

               end;

            end;

         end;

end;

procedure TfrmRapportHistorique.cmdSondageInactifsClick(Sender: TObject);
label lAddLune;
var peGalaxie: PGalaxiePlanete;
    Coord, nTmp: TPlanetLocation;
    iPosition: integer;
    iSystem: integer;
    Duree: int64;

    NbAjoute: integer;
begin
       if FInfosBaseDeDonneCharge = false then begin
          // aucune base de données chargées...
          Status(_('Aucune base de données chargée'));
          exit;
       end;

       
   SondageLockCmd(false);

   if seSondageSystemEnd.Value < seSondageSystemStart.Value then begin
      iSystem := seSondageSystemEnd.Value;
      seSondageSystemEnd.Value := seSondageSystemStart.Value;
      seSondageSystemStart.Value := iSystem;
   end;


   FCurrDate := DateTimeToUnix(Now);
   NbAjoute := 0;

   Coord.Galaxie := FBase2DonneesPlanete.Galaxie;

   for iSystem := seSondageSystemStart.Value to seSondageSystemEnd.Value do begin

       Coord.SystemSolaire := iSystem;

       for iPosition := 1 to  15 do begin
           Coord.Position := iPosition;

           peGalaxie := FBase2DonneesPlanete.Get_Pointeur(Coord);

           if peGalaxie <> nil then begin
              Duree := FCurrDate - peGalaxie.Date;

              if Duree <= seSondageDureePourEtrePrisEnCompte.Value then begin

                  if (sfcFlagsIsIn(CNT_GALAXIE_FLAGS_INACTIF_2SEMAINES, peGalaxie.Flags)) or
                     (sfcFlagsIsIn(CNT_GALAXIE_FLAGS_INACTIF_4SEMAINES, peGalaxie.Flags)) then begin

                     // Inactif, cependant, il doit être sondable, c'est à dire
                     // ne pas être en mode vacances

                     if chkSondageAddOnlyLune.Checked = false then begin
                        if SondageCheckAndTryToAddThisCoord(Coord, peGalaxie, false) then begin
                           Inc(NbAjoute);
                        end;
                     end else begin
                        goto lAddLune;
                     end;


                     if chkSondageInclureLune.Checked then begin
lAddLune:
                        if peGalaxie.Lune.Surface > 0 then begin
                           // la planète possède une lune

                           nTmp := Coord;
                           nTmp.Position := nTmp.Position + CNT_POSITION_LUNE;
                           if SondageCheckAndTryToAddThisCoord(nTmp, peGalaxie, false) then begin
                              Inc(NbAjoute);
                           end;
                        end;

                     end;
                  end;



              end else begin
                 Status('Sondage - Non pris en compte car trop ancien: ' + mbtPlanetLocationToStr(peGalaxie.Location));

              end;

           end else begin
              Status('Sondage - Non scanné: ' + mbtPlanetLocationToStr(Coord));

           end;

       end;

   end;


   Status(format(_('Sondage - Total ajouté: %d'), [NbAjoute]));

   SondageLockCmd(true);

end;

procedure TfrmRapportHistorique.GalaxieNumeroColorationFromCurrPlanete;
var pDepart: TPlanetLocation;
begin

    FCurrentPlayer.Conf.SondageLastPlaneteSel := cbSondagePlanete.ItemIndex;


    if (FInfosBaseDeDonneCharge = false) or (FBase2DonneesRapports.Galaxie < 1) then begin
       lblSondageGalaxie.Caption    := _('Aucune');
       lblSondageGalaxie.Font.Color := clRed;

    end else if cbGalaxieScanPlanete.ItemIndex >= 0 then begin
       lblSondageGalaxie.Caption := IntToStr(FBase2DonneesRapports.Galaxie);

       pDepart := SpiderGalaxieTextPlaneteToLocation(cbGalaxieScanPlanete.Text);

       if pDepart.Galaxie <> FBase2DonneesRapports.Galaxie then begin
          lblSondageGalaxie.Font.Color := clRed;

       end else begin
          lblSondageGalaxie.Font.Color := clWindowText;
       end;

       
    end else begin
       // aucune planète de sélectionnée
       lblSondageGalaxie.Caption := _('Planète invalide');
       lblSondageGalaxie.Font.Color := clRed;
    end;


    lblSpiderGalaxieScan.Font.Color := lblSondageGalaxie.Font.Color;
    lblSpiderGalaxieScan.Caption    := lblSondageGalaxie.Caption;
end;

procedure TfrmRapportHistorique.cbGalaxieScanPlaneteChange(Sender: TObject);
begin
    cbSondagePlanete.ItemIndex           := cbGalaxieScanPlanete.ItemIndex;
    GalaxieNumeroColorationFromCurrPlanete;
end;

procedure TfrmRapportHistorique.cbSondagePlaneteChange(Sender: TObject);
var pDepart: TPlanetLocation;
begin
    cbGalaxieScanPlanete.ItemIndex       := cbSondagePlanete.ItemIndex;
    GalaxieNumeroColorationFromCurrPlanete;
end;

procedure TfrmRapportHistorique.cmdSondageClearAllClick(Sender: TObject);
var r: integer;
begin

    if FCurrentPlayer.SondagePlanetesList.Count = 0 then begin
       Status(_('Sondage - Aucune planète à effacer'));
       exit
    end;

    r := Application.MessageBox('Si vous videz toute la liste, vous risquez de resonder plusieurs fois les même planètes. Voulez-vous continuer ?', 'Remarque', MB_YESNOCANCEL + MB_ICONQUESTION + MB_DEFBUTTON2);

    if r <> ID_YES then begin
       // L'utilisateur à choisit Non ou Annuler
       Status(_('Sondage - Le vidage de la liste n''a pas été effectué (annulé au dernier moment)'));
       exit;
    end;


    Status('Sondage - Toutes les planètes ont été effacé (' + IntToStr(FCurrentPlayer.SondagePlanetesList.Count) + ' éléments)');
    FCurrentPlayer.SondagePlanetesList.Clear;

    
    // Quand on vide la liste, on peut la mettre à jour sans problème
    // car il n'y a plus d'élément dedans
    cmdSondageUpdateSGridClick(nil);
end;

procedure TfrmRapportHistorique.cmdSondageClearNonSondeClick(Sender: TObject);
var r: integer;
begin

    r := Application.MessageBox('Etes vous certain ?', 'Alors ?', MB_YESNOCANCEL + MB_ICONQUESTION + MB_DEFBUTTON2);
    if r <> ID_YES then begin
       // L'utilisateur à choisit Non ou Annuler
       Status(_('Sondage - La suppression des éléments non sondé n''a pas été effectuée (annulé au dernier moment)'));
       exit;
    end;

    r := FCurrentPlayer.SondagePlanetesList.ClearNonSondee;

    Status('Sondage - Planètes non sondées effacées: ' + IntToStr(r));
end;

procedure TfrmRapportHistorique.cmdSondageStartClick(Sender: TObject);
begin
       if FInfosBaseDeDonneCharge = false then begin
          // aucune base de données chargées...
          Status(_('Aucune base de données chargée'));
          exit;
       end;


    cmdMessageListGet.Enabled := false;
    cmdSondageStart.Enabled   := cmdMessageListGet.Enabled;

    // Change la planète
    // La planète sélectionnée est obligatoirement la même que
    // celle dans Spider
    if SpiderChangePlaneteToGalaxieScanSelected < 1 then begin
       Status(_('Sondage - Echec de changement de planète'));
       cmdMessageListGet.Enabled := true;
       cmdSondageStart.Enabled   := cmdMessageListGet.Enabled;
       Exit;
    end;



    if chkDisableSecuSondage.Checked = false then begin
       if FCurrPlayerCurrPlanete.FLocation.Galaxie <> FBase2DonneesPlanete.Galaxie then begin
          Status(_('La planète utilisée pour sonder est située dans une galaxie différente (sécurité)'));
          cmdMessageListGet.Enabled := true;
          cmdSondageStart.Enabled   := cmdMessageListGet.Enabled;
          exit;
       end;
    end;

    if chkSondageReorganiseList.Checked then begin
       FCurrentPlayer.SondagePlanetesList.ReorganiseFromSourceRnd(SpiderGalaxieGetSelectedPlanete);
       cmdSondageUpdateSGridClick(nil);
    end;

    FSondageDernierSystemeSolaireSonde := -1;
    FSondageNbEnvoiEffectue            :=  0;

    // est déjà à false normalement
    FInTimerSondage := false;
    
    if chkSondageFast.Checked then
       timSondage.Interval := SONDAGE_INTERVAL_DURING_SONDAGE_FAST
    else
       timSondage.Interval := SONDAGE_INTERVAL_DURING_SONDAGE;

    FSondageDernierEnvoiPrevuPour := DateTimeToUnix(Now);
    Status(_('Sondage - Début des sondages'));
    Sleep(5);
    FSondageDejaPrevuFin := 0;

    cmdMessageListGet.Caption := _('Boucle d''envoi en cours');


    timSondageTimer(nil);

end;

procedure TfrmRapportHistorique.cmdSondageStopClick(Sender: TObject);
begin

    FInTimerSondage := true;
    timSondage.Interval := 0;
    Sleep(2);
    Status(_('Sondage - Fin des sondages'));

    cmdSondageStart.Enabled := true;
    cmdSondageStop.Enabled := false;

    cmdMessageListGet.Caption := _('Lire tous les messages');
    cmdMessageListGet.Enabled := true;

    timSondage.Interval := 0;
end;

procedure TfrmRapportHistorique.menGalaxieChangeDelayClick(Sender: TObject);
var m: TMenuItem;
begin
    m := TMenuItem(Sender);
    seSpiderGalaxieDureeRecent.Value := m.Tag;
    seSondageDureePourEtrePrisEnCompte.Value := m.Tag;
end;

procedure TfrmRapportHistorique.seSpiderGalaxieDureeRecentChange(
  Sender: TObject);
var sStr: string;
begin

   sStr := ESBDGetDureeStrings(seSpiderGalaxieDureeRecent.Value, false);
   seSpiderGalaxieDureeRecent.Hint := sStr;
   seSpiderGalaxieDureeRecent.ShowHint := true;
   seSpiderGalaxieDureeRecent.ShowHint := true;
end;

procedure TfrmRapportHistorique.seSondageDureePourEtrePrisEnCompteChange(
  Sender: TObject);
var sStr: string;
begin
   sStr := ESBDGetDureeStrings(seSondageDureePourEtrePrisEnCompte.Value, false);
   seSondageDureePourEtrePrisEnCompte.Hint := sStr;
   seSondageDureePourEtrePrisEnCompte.ShowHint := true;

   FCurrentPlayer.Conf.SondageDureeToBeConsideredAsRecent := seSondageDureePourEtrePrisEnCompte.Value;
end;

procedure TfrmRapportHistorique.timSondageTimer(Sender: TObject);
label lblMaxFlotte;
var pe: PPlaneteASonder;
    res: TFlotteEnvoiRes;
    sDiff: integer;
    bStopSondage: boolean;
    iDiffSystem: integer;
    iSleep: integer;
begin



    if FInTimerSondage then begin
       Status(_('Sondage - In Timer'));
       cmdSondageStop.Enabled := true;
       exit;
    end;

    bStopSondage := false;
    
    cmdSondageStart.Enabled := false;
    cmdSondageStop.Enabled := true;

    msgUpdateSondagesDateOnly(sgSondages, FCurrentPlayer.SondagePlanetesList);

    FCurrDate := DateTimeToUnix(Now);

    if FSondageDernierEnvoiPrevuPour <= FCurrDate then begin
       // Envoi une sonde

       pe := FCurrentPlayer.SondagePlanetesList.GetNextASonder;

       if pe = nil then begin
          Status(_('Sondage - Plus d''élément à sonder'));
          timSondage.Interval := SONDAGE_INTERVAL_QUAND_PLUSRIENASONDER;

          if FSondageDejaPrevuFin = 0 then begin
             formConfirmation.ShowNotif(_('Terminé'));

          end else if FSondageDejaPrevuFin = 3 then begin
             formConfirmation.ShowNotif(_('Terminé'));

             cmdSondageStopClick(nil);

             if chkSondageEmettreBeepAtEnd.Checked then begin
                Windows.Beep(440, 100);
                DoSleep5(200);
                Windows.Beep(440, 100);
                DoSleep5(200);
                Windows.Beep(440, 100);
             end;

             if chkSondageLireMsgAtEnd.Checked then begin
                cmdMessageListGetClick(nil);
             end;
             
          end;

          Inc(FSondageDejaPrevuFin);

          exit;

       end else if (timSondage.Interval = SONDAGE_INTERVAL_QUAND_PLUSRIENASONDER)
                or (timSondage.Interval = SONDAGE_INTERVAL_QUAND_FLOTTEMAXIATTEINT) then begin

          // Remet un interval plus court
          if chkSondageFast.Checked then
             timSondage.Interval := 950
          else
             timSondage.Interval := SONDAGE_INTERVAL_DURING_SONDAGE;

       end;

       FInTimerSondage := true;


       timSondage.Interval := 60000;


       if (FSondageDernierSystemeSolaireSonde > 0) and (pe.Coord.SystemSolaire <> FSondageDernierSystemeSolaireSonde) then begin
           // on change de système solaire
           iDiffSystem := pe.Coord.SystemSolaire - FSondageDernierSystemeSolaireSonde;

           if iDiffSystem < 0 then begin
              iDiffSystem := -1 * iDiffSystem;
           end;


           if chkSondageSystemDelay.Checked then begin
              Status(format(_('Changement de système solaire (différence: %d)'), [iDiffSystem]));

              Randomize;
              iSleep := seSondageSystemDelay.Value + Random(seSondageSystemDelayHumain.Value);

              if iDiffSystem > 1 then begin
                 Dec(iDiffSystem);
                 iSleep := iSleep + iDiffSystem;
              end;

              iSleep := iSleep * 1000;

              // Ajoute des millisecond
              iSleep := iSleep + Random(700);

              Status(format(_('Pause de: %d ms'), [iSleep]));
              FCurrentPlayer.DoSleep(iSleep);
           end;

       end;
       FSondageDernierSystemeSolaireSonde := pe.Coord.SystemSolaire;

       Status('Sondage - Cible: ' + mbtPlanetLocationToStr(pe.Coord) + ' - Nombre de sondes: ' + IntToStr(pe.NbSondes));

       // Envoi les sondes
       if FCurrentPlayer.IsLoggedAndCanDoSomething then begin
          res := FCurrentPlayer.ProceedSondage(pe.Coord, pe.NbSondes);
       end else begin
          res := ferShouldRetryButNotError;
       end;



       if timSondage.Interval = 0 then begin
          // Le sondage a été arrêté
          bStopSondage := true;
       end;

       if chkSondageFast.Checked then
          timSondage.Interval := SONDAGE_INTERVAL_DURING_SONDAGE_FAST
       else
          timSondage.Interval := SONDAGE_INTERVAL_DURING_SONDAGE;

       

       // Le temps de téléchargement des 4 pages a pris du temps, on réactualise
       // la date en réutilisant DateTimeToUnix
       FCurrDate := DateTimeToUnix(Now);

       case res of
           ferFatalError: begin
                          Status(_('Sondage - Fatal error'));
                          formConfirmation.ShowNotifErreur(_('Erreur'));
                          cmdSondageStopClick(nil);
                     end;
                     
           ferSocketError, ferNotOrReLoginCertain: begin
                          Status(_('Sondage - Pas loggé, ou devrait se relogger'));

                          if chkSondageEssaiMultiple.Checked then begin

                             Dec(pe.DateSondage);

                             if pe.DateSondage < -8 then begin
                                // déjà égal à -9
                                Status('Sondage - Pas loggé, ou devrait se relogger - Le n-ième essai a aussi échoué');
                                formConfirmation.ShowNotifErreur('Erreur');
                                cmdSondageStopClick(nil);

                             end else begin
                                if pe.DateSondage > -3 then
                                   FSondageDernierEnvoiPrevuPour := FCurrDate + 5
                                else
                                   FSondageDernierEnvoiPrevuPour := FCurrDate + 18;

                                   
                             end;

                          end else begin

                             if pe.DateSondage = -2 then begin
                                // déjà égal à -2
                                Status('Sondage - Pas loggé, ou devrait se relogger - Le second essai a aussi échoué');
                                formConfirmation.ShowNotifErreur('Erreur');
                                cmdSondageStopClick(nil);

                             end else begin
                                pe.DateSondage := -2;

                                FSondageDernierEnvoiPrevuPour := FCurrDate + 5;
                             end;

                          end;

                     end;

           ferShouldRetryButNotError: begin
                          Status('Sondage - Doit réessayer le sondage - Autre action en cours (géré automatiquement)');

                          FSondageDernierEnvoiPrevuPour := FCurrDate + 6;

                     end;
           ferShouldRetry: begin
                          Status(_('Sondage - Doit réessayer le sondage (géré automatiquement)'));


                          if chkSondageEssaiMultiple.Checked then begin

                             Dec(pe.DateSondage);

                             if pe.DateSondage < -8 then begin
                                // déjà égal à -9
                                Status(_('Sondage - Should retry - Le n-ième essai a aussi échoué'));
                                formConfirmation.ShowNotifErreur('Erreur');
                                cmdSondageStopClick(nil);

                             end else begin
                                if pe.DateSondage > -3 then
                                   FSondageDernierEnvoiPrevuPour := FCurrDate + 6
                                else
                                   FSondageDernierEnvoiPrevuPour := FCurrDate + 18;

                             end;

                          end else begin

                             if pe.DateSondage = -2 then begin
                                // déjà égal à -2
                                Status(_('Sondage - Should retry - Le second essai a aussi échoué'));
                                formConfirmation.ShowNotifErreur('Erreur');
                                cmdSondageStopClick(nil);

                             end else begin
                                pe.DateSondage := -2;

                                FSondageDernierEnvoiPrevuPour := FCurrDate + 6;
                             end;

                          end;


                     end;

           ferPlaneteInvalid: begin
                          // La planète n'existe plus
                          Status('Sondage - La planète est invalide (vacances, détruite, protection des newbz): ' + mbtPlanetLocationToStr(pe.Coord));
                          pe.DateSondage := FCurrDate;
                          if chkSondageFast.Checked then
                             FSondageDernierEnvoiPrevuPour := FCurrDate + 3
                          else
                             FSondageDernierEnvoiPrevuPour := FCurrDate + 5;

                          sggUpdateFlotteList(sgGridFlotteList, FCurrentPlayer.cFlotteVaisseaux.FlotteList, FCurrentPlayer);

                     end;



           ferSuccess: begin
                          // Envoi réussit
                          Status('Sondage - Envoi réussit sur ' + mbtPlanetLocationToStr(pe.Coord));
                          pe.DateSondage := FCurrDate;

                             if chkSondageFast.Checked then
                                FSondageDernierEnvoiPrevuPour := FCurrDate + 1
                             else
                                FSondageDernierEnvoiPrevuPour := FCurrDate + 5;


                          Inc(FSondageNbEnvoiEffectue);

                          sggUpdateFlotteList(sgGridFlotteList, FCurrentPlayer.cFlotteVaisseaux.FlotteList, FCurrentPlayer);

                     end;

           ferNoVaisseaux: begin
                          Status('Sondage - Aucun vaisseau de disponible sur cette planète (simulation max flotte) ####################');
                          goto lblMaxFlotte;

                          (*
                          timSondage.Interval := SONDAGE_INTERVAL_QUAND_FLOTTEMAXIATTEINT;
                          FSondageDernierEnvoiPrevuPour := FCurrDate + 5;
                          //cmdSondageStopClick(nil);

                          UpdateFlotteList(sgGridFlotteList, FCurrentPlayer.cFlotteVaisseaux.FlotteList);
                          *)

                     end;


           ferFlotteMaxAtteinte: begin
                  lblMaxFlotte:
                          Status('Sondage - Nombre flotte maximal atteint, mise en attente de quelques secondes @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
                          timSondage.Interval := SONDAGE_INTERVAL_QUAND_FLOTTEMAXIATTEINT;
                          FSondageDernierEnvoiPrevuPour := FCurrDate + 5;

                          sggUpdateFlotteList(sgGridFlotteList, FCurrentPlayer.cFlotteVaisseaux.FlotteList, FCurrentPlayer);

                          sDiff := FCurrentPlayer.cFlotteVaisseaux.FlotteList.GetDateFirstRetour;
                          if sDiff > 0 then begin
                             sDiff := sDiff + FCurrentPlayer.DifferenceHeureLocaleHeureServeur;
                             sDiff := sDiff - FCurrDate;

                             if (sDiff >= 0) and (sDiff < 180) then begin
                                Status('Sondage - Nombre flotte maximal atteint, flotte libre estimée dans: ' + IntToStr(sDiff) + ' secondes');
                                FSondageDernierEnvoiPrevuPour := FCurrDate + sDiff + 3;

                                if chkSondageFast.Checked then
                                   timSondage.Interval := 950
                                else
                                   timSondage.Interval := SONDAGE_INTERVAL_DURING_SONDAGE;


                                if (FSondageNbEnvoiEffectue > 3) and (sDiff > 10) and (chkSondageLireMsgAtEnd.Checked) then begin
                                   Status('Profite pour télécharger les messages');
                                   
                                   // profite pour lire les messages
                                   cmdMessageListGetClick(nil);

                                   // réinitialisation
                                   FSondageNbEnvoiEffectue := 0;
                                end;

                             end else begin
                                // prochainement peut-être
                                // ou lag de serveur (ce qui arrive assez souvent quand même)
                                FSondageDernierEnvoiPrevuPour := FCurrDate + 5;

                                if chkSondageFast.Checked then
                                   timSondage.Interval := 950
                                else
                                   timSondage.Interval := SONDAGE_INTERVAL_DURING_SONDAGE;

                             end;

                          end else begin
                             // utilise la date de premier impact ?

                          end;

                          // FCurrDate


                     end;
           else begin
                     Status(_('Sondage - Status d''erreur inconnu'));
                     formConfirmation.ShowNotifErreur(_('Erreur'));
                     cmdSondageStopClick(nil);
                end;
       end;



    end;


    FInTimerSondage := false;

    if bStopSondage then begin
       timSondage.Interval := 0;
    end;

end;

procedure TfrmRapportHistorique.cmdSondageUpdateSGridClick(Sender: TObject);
begin
    if cmdSondageUpdateSGrid.Enabled = false then begin
       exit;
    end;
    cmdSondageUpdateSGrid.Enabled := false;
    UpdateSondages(sgSondages);
    cmdSondageUpdateSGrid.Enabled := true;
end;

procedure TfrmRapportHistorique.cmdSondageUpdateDateOnlyClick(Sender: TObject);
begin
    cmdSondageUpdateDateOnly.Enabled := false;
    msgUpdateSondagesDateOnly(sgSondages, FCurrentPlayer.SondagePlanetesList);
    cmdSondageUpdateDateOnly.Enabled := true;
end;

procedure TfrmRapportHistorique.sgVaisseauxGetEditorType(Sender: TObject; ACol,
  ARow: Integer; var AEditor: TEditorType);
var i: integer;
begin

   if (ARow > 0) and (ACol = 1) and (FCurrVaisseuxList <> nil) and (FCurrVaisseuxList.Count > 0) then begin
      i := ARow - 1;

      if (i < 0) or (i >= FCurrVaisseuxList.Count) then
         exit;

      AEditor := edSpinEdit;

      FCurrVaisseauxItem := FCurrVaisseuxList.Items[i];

      // Définit les propriétés du spinedit
      sgVaisseaux.SpinEdit.MinValue := 0;
      sgVaisseaux.SpinEdit.MaxValue := FCurrVaisseauxItem.Max;
      sgVaisseaux.SpinEdit.EditAlign := eaLeft;
   end;

end;

procedure TfrmRapportHistorique.sgVaisseauxCanEditCell(Sender: TObject; ARow,
  ACol: Integer; var CanEdit: Boolean);
var i: integer;
begin
   CanEdit := false;

   if (ARow > 0) and (ACol = 1) and (FCurrVaisseuxList <> nil) and (FCurrVaisseuxList.Count > 0) then begin
      i := ARow - 1;
      if (i < 0) or (i >= FCurrVaisseuxList.Count) then
         exit;

      CanEdit := true;
   end;
end;

procedure TfrmRapportHistorique.sgPlanetesDblClickCell(Sender: TObject; ARow,
  ACol: Integer);
var i: integer;
begin
    // gbPlanete
    i := ARow - 1;

    if (i < 0) or (i >= FBase2DonneesRapports.Count) then exit;

    SondageCurrentSelPlaneteInGridList;
end;

procedure TfrmRapportHistorique.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
var r: integer;
begin

    CanClose := true;

    // verifie si l'on est pas en train de faire quelque chose
    if (FInfosBaseDeDonneCharge) and (FQuitDirect = false) then begin


       if (timSondage.Interval > 0) or (FCurrentPlayer.sockHTTP.State <> httpReady) then begin
           r := Application.MessageBox('Quitter maintenant ?', 'Etes vous sûr ?', MB_YESNOCANCEL);

           if r <> ID_YES then begin
              // Non ou annuler
              CanClose := false;
              exit;
           end;
       end;


    end;

    // sauvegardé dans AppTerminating
    //FCurrentPlayer.Conf.SaveToFile('');


    FLocalSetting.SaveToFile('', [lsoEnteteValues, lsoIniData]);

    if CanClose and (AppTerminating = false) then begin
       CanClose := false;
    end else begin
       StopTimers;
    end;

end;


procedure TfrmRapportHistorique.SondageCurrentSelPlaneteInGridList;
var i: integer;
    peSondage: PPlaneteASonder;
    peGalaxie: PGalaxiePlanete;
begin

    if FCurrentRapport = nil then begin
       Status(_('Liste des rapports - Erreur'));

    end else begin


       if sfcFlagsIsIn(FLAG_NE_JAMAIS_ATTACK, FCurrentRapport.Flags) then begin
          // On ne doit pas l'attaquer
          Status('Liste des rapports - Double click, non sondé car le flag de protection d''attaque est activé: ' + mbtPlanetLocationToStr(FCurrentRapport.PlaneteLocation));
          exit;
       end;




       peGalaxie := FBase2DonneesPlanete.Get_Pointeur(FCurrentRapport.PlaneteLocation);

       if (peGalaxie <> nil) and (FCurrentPlayer.Conf.IsAllianceAlliees(peGalaxie.Alliance)) then begin
          // On ne le sonde pas
          Status('Sondage - Non ajouté car alliance alliée: ' +  mbtPlanetLocationToStr(peGalaxie.Location) + ' [' + peGalaxie.Alliance + ']');
          exit;
       end;


       peSondage := FCurrentPlayer.SondagePlanetesList.AddIfNotExistCoord(FCurrentRapport.PlaneteLocation);


       if peSondage <> nil then begin
          peSondage.NbSondes := FCurrentPlayer.Conf.SondesNbMini;

          Status('Liste des rapports - Double click, ajout à la liste à sonder: ' + mbtPlanetLocationToStr(FCurrentRapport.PlaneteLocation));

          if sfcFlagsIsIn(FLAG_NIV_ESP_ELEVE, FCurrentRapport.Flags) then begin
             // Envoi plus de sondes
             peSondage.NbSondes := FCurrentPlayer.Conf.SondesNbNivEsp;

          end;

          // Met à jour la plante en rajoutant ** dans la grille
          cmdUpdatePlaneteClick(nil);

          // Met à jour la liste des planètes sondées
          UpdateSondages(sgSondages);

       end else begin
          Status('Liste des rapports - Double click, planète à sonder déjà présente: ' + mbtPlanetLocationToStr(FCurrentRapport.PlaneteLocation));

       end;


    end;

end;

procedure TfrmRapportHistorique.sgPlanetesRecentesDblClickCell(Sender: TObject; ARow, ACol: Integer);
var i: integer;
begin

    // gbPlanete
    i := ARow - 1;

    if (i < 0) or (i >= FBase2DonneesRapports.Count) then exit;

    
    if ssCtrl in FLastShiftStateClickInList then begin
       menAjouterListeDattaqueClick(nil);
       
    end else begin
       SondageCurrentSelPlaneteInGridList;
    end;



end;

procedure TfrmRapportHistorique.sgPlanetesRecentesMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
   FLastShiftStateClickInList := Shift;
end;

procedure TfrmRapportHistorique.sgPlanetesPoulesDorDblClickCell(Sender: TObject;
  ARow, ACol: Integer);
var i: integer;
begin

    // gbPlanete
    i := ARow - 1;

    if (i < 0) or (i >= FBase2DonneesRapports.Count) then exit;

    SondageCurrentSelPlaneteInGridList;
end;


procedure TfrmRapportHistorique.menAttaquerClick(Sender: TObject);
var TotalRessource: integer;
begin

    if FCurrentRapport = nil then exit;

    seAttaqueGalaxie.Value := FCurrentRapport.PlaneteLocation.Galaxie;
    seAttaqueSystem.Value := FCurrentRapport.PlaneteLocation.SystemSolaire;


    if mbtIsLune(FCurrentRapport.PlaneteLocation) then begin
       seAttaquePosition.Value := mbtGetRealPosition(FCurrentRapport.PlaneteLocation.Position);
       chkAttaqueLune.Checked  := true;
    end else begin
       seAttaquePosition.Value := FCurrentRapport.PlaneteLocation.Position;
       chkAttaqueLune.Checked  := false;
    end;


    AttaqueLoadStatsCible;


    ////////////
    // Nombre de GT pour récupérer toute les ressources possible
    //TotalRessource := FCurrentRapport.Ressource.Metal + FCurrentRapport.Ressource.Cristal + FCurrentRapport.Ressource.Deuterium;
    //TotalRessource := TotalRessource shr 1;

    TotalRessource := FCurrentPlayer.GetCapaciteDeFret(FCurrentRapport.Ressource);


    // On ne peut prendre au maximum la moitié des ressources
    FNbGTForCurrentRapport := Ceil(TotalRessource / 24500);

    if frac(TotalRessource / 24500) > 0.7 then begin
       Inc(FNbGTForCurrentRapport);
    end;

    FNbPTForCurrentRapport := Ceil(TotalRessource / 5000) + 1;

    pcUniversRapports.ActivePageIndex := tabAttaque.PageIndex;
    cbAttaqueSpeedRatio.ItemIndex := 0;

end;

procedure TfrmRapportHistorique.menVoirSystmeSolaireClick(Sender: TObject);
begin
    if FCurrentRapport = nil then exit;

    seSystemSolairChoix.Value := FCurrentRapport.PlaneteLocation.SystemSolaire;
    LoadAndUpdateSystemSolaire(seSystemSolairChoix.Value);

    // Affiche l'onglet
    pcUniversRapports.ActivePageIndex := tabSystemSolaire.PageIndex;
end;


// La fonction renvoit le nombre de rapport d'espionnage ajouté
function TfrmRapportHistorique.TraitementMsgList(MsgList: TCollectionOGMessage): integer;
label lBackupRapport;
var FBackup, FBackupFlotte: TextFile;
    pe: POGMessage;
    i: integer;
begin

   Result := 0;

   if MsgList.Count > 0 then begin

      AssignFile(FBackup, FFileBackupMsgList);

      {$I-}
      Append(FBackup);
      {$I+}

       // IOResult renvoie 0 => cela signifie que la dernière opération d'E/S a réussi
       if NoT(IOResult = 0) then begin
          // erreur IO
          Status(_('Erreur fatale: Erreur d''ouverture du fichier backup: ') + FFileBackupMsgList);
          Result := -1;
          exit;
       end;


      AssignFile(FBackupFlotte, FFileBackupMsgFlotte);

      {$I-}
      Append(FBackupFlotte);
      {$I+}

       // IOResult renvoie 0 => cela signifie que la dernière opération d'E/S a réussi
       if NoT(IOResult = 0) then begin
          // erreur IO
          Status(_('Erreur fatale: Erreur d''ouverture du fichier backup: ') + FFileBackupMsgFlotte);

          CloseFile(FBackup);
          
          Result := -1;
          exit;
       end;



      for i := 0 to MsgList.Count - 1 do begin

           pe := MsgList.Items[i];


           Status(format(_('Reçu le %s de %s (dme: %s)'), [pe.Date, pe.Emetteur, DateTimeToStr(UnixToDateTime(pe.DateEstimation))]));
           Status(format(_('Sujet: %s'), [pe.Sujet]));
           Status(format(_('Contenu: %s'), [pe.Contenu]));


           if (pos(LangParsing.GetData('message_poslw_subject_rapport_esp', 'espion'), lowercase(pe.Sujet)) > 0) and (pos('[', pe.Sujet) > 0) then begin
              // Sujet: Rapport de espionnage PlanetName [1:8:1]
              // Rapport d'espionnage possible
              txtRapport.Text := pe.Contenu;
              Sleep(2);
              Application.ProcessMessages;
              Sleep(2);

              if AnalyseRapport(pe.Contenu, False, False, False) < 0 then begin
                 Status(_('Erreur d''ajout de rapport... (sauvegardé dans le fichier backup)'));

                 // -1 car erreur, mais on contenu avec les autres messages, qui eux
                 // risque d'être bien ajouté et donc de produire un Inc(Result)
                 Result := -11;
                 goto lBackupRapport;

              end else begin
                 Inc(Result);
              end;



           end else if (pos(LangParsing.GetData('message_poslw_subject_retour_flotte', 'etour de flotte'), lowercase(pe.Sujet)) > 0) then begin
              // retour de flotte
              WriteLn(FBackupFlotte, '');
              WriteLn(FBackupFlotte, '');
              WriteLn(FBackupFlotte, 'DateAjout=' + IntToStr(FCurrDate));
              WriteLn(FBackupFlotte, 'DateMsg=' + IntToStr(pe.DateEstimation));

              //WriteLn(FBackupFlotte, 'Reçu le ' + pe.Date  + ' de ' + pe.Emetteur + ' -  Sujet: ' + pe.Sujet);
              WriteLn(FBackupFlotte, format(_('Reçu le %s de %s -  Sujet: %s'), [pe.Date, pe.Emetteur, pe.Sujet]));

              WriteLn(FBackupFlotte, pe.Contenu);



           end else begin
              // Si c'est un rapport, il sera quand même sauvegardé dans le fichier backup
              // des rapports dans AnalyseRapport
lBackupRapport:

              if pos('oitation du champ de ', lowercase(pe.Sujet)) > 0 then begin

              end;


              WriteLn(FBackup, '');
              WriteLn(FBackup, '');
              WriteLn(FBackup, 'DateAjout=' + IntToStr(FCurrDate));
              WriteLn(FBackup, 'DateMsg=' + IntToStr(pe.DateEstimation));
              
              //WriteLn(FBackup, 'Reçu le ' + pe.Date  + ' de ' + pe.Emetteur + ' -  Sujet: ' + pe.Sujet);
              WriteLn(FBackup, format(_('Reçu le %s de %s -  Sujet: %s'), [pe.Date, pe.Emetteur, pe.Sujet]));


              WriteLn(FBackup, pe.Contenu);
           end;

       end;

       CloseFile(FBackup);
       CloseFile(FBackupFlotte);

   end else begin
       Status(_('Pas de message'));
   end;

end;


procedure TfrmRapportHistorique.cmdMessageListGetClick(Sender: TObject);
var r, i: integer;
    List2Msg: TCollectionOGMessage;
    NbRapportEspAjoute: integer;
    NbTotalRapportEspAjoute: integer;

    bStateEnable: boolean;
begin


    bStateEnable := cmdMessageListGet.Enabled;

    cmdMessageListGet.Enabled := false;
    //FRapportTrieLorsDeLajout := false;

    List2Msg := TCollectionOGMessage.Create;
    FCurrDate := DateTimeToUnix(Now);
    NbTotalRapportEspAjoute := 0;

    repeat
        List2Msg.Clear;
        r := FCurrentPlayer.ProceedGetMessagesList(List2Msg, true, FCurrentPlayer.Conf.MessageListSauvegardeRapportDeCombat);

        Status(format(_('GetMsgL Resultat: %d'), [r]));

        // Boucle pour télécharger tout les messages
        NbRapportEspAjoute := TraitementMsgList(List2Msg);
        if NbRapportEspAjoute < 0 then begin
           // erreur d'ajout de rapport
           // ne continue pas le téléchargement des autres messages
           Status(_('Erreur de traitement des messages, arrêt de la récolte des messages (erreur possible: base de données non chargé, ou galaxie incorrecte)'));
           NbTotalRapportEspAjoute := 1;
           break;
        end else begin
           NbTotalRapportEspAjoute := NbTotalRapportEspAjoute + NbRapportEspAjoute;
        end;

        // Mets à jour que la liste des recents
        UpdateAllSpec(sgPlanetesRecentes, FBaseRecent);


    until (List2Msg.Count = 0) or (r < 1);



    List2Msg.Free;

    if NbTotalRapportEspAjoute > 0 then begin
       Status('Total rapport d''espionnage ajouté: ' + IntToStr(NbTotalRapportEspAjoute));
       FBaseRecent.TrieParGT;

       //FRapportTrieLorsDeLajout := true;
    
       // mets tout à jour
       UpdateAll;
    end;

    cmdMessageListGet.Enabled := bStateEnable;

end;

procedure TfrmRapportHistorique.seSondageSystemStartChange(Sender: TObject);
begin
    FCurrentPlayer.Conf.SondageSystemRangeStart := seSondageSystemStart.Value;
end;

procedure TfrmRapportHistorique.seSondageSystemEndChange(Sender: TObject);
begin
    FCurrentPlayer.Conf.SondageSystemRangeEnd := seSondageSystemEnd.Value;
end;


procedure TfrmRapportHistorique.seSondageIgnoreDelayLastSondageChange(Sender: TObject);
var sStr: string;
begin
   FCurrentPlayer.Conf.SondageDureeToDontBeSondeANouveau := seSondageIgnoreDelayLastSondage.Value;

   sStr := ESBDGetDureeStrings(seSondageIgnoreDelayLastSondage.Value, false);
   seSondageIgnoreDelayLastSondage.Hint := sStr;
   seSondageIgnoreDelayLastSondage.ShowHint := true;
end;


procedure TfrmRapportHistorique.UpdateSpeedAndDeutUsed;
var pDepart, Cible : TPlanetLocation;
    lRecycleur: TCollectionVaisseauSelInfos;

    trajetDistance: integer;
    trajetDuree   : integer;
    trajetDureeRecycl: integer; // durée du trajet pour les recycleurs
    xRatioSpeed: integer;
    x1: integer;
    iConsomation: integer;
begin

    if FCurrentPlayer = nil then exit;
    if FCurrVaisseuxList = nil then exit;



    Cible.Galaxie       := seAttaqueGalaxie.Value;
    Cible.SystemSolaire := seAttaqueSystem.Value;
    Cible.Position      := seAttaquePosition.Value;

    trajetDistance := mfdgGetDistance(FCurrentPlayer.curPlanete.FLocation, Cible);
    //trajetDuree    := mfdgGetDurationTrajet100pSF(FCurrentPlayer.curPlanete.FLocation, Cible, FCurrVaisseuxList.GetSpeedUsed, FCurrentPlayer.Conf.UniversSpeedFactorFlotte);



    if cbAttaqueSpeedRatio.ItemIndex < 0 then
       cbAttaqueSpeedRatio.ItemIndex := 0;
    x1 := 10 - cbAttaqueSpeedRatio.ItemIndex;

    xRatioSpeed := x1 * 10;
    trajetDuree := mfdgGetDurationTrajet100p(FCurrentPlayer.curPlanete.FLocation, Cible, FCurrVaisseuxList.GetSpeedUsed, xRatioSpeed, FCurrentPlayer.Conf.UniversSpeedFactorFlotte);

    if FCurrVaisseuxList.GetNbVaisseauxDispo(CNT_GID_VAISSEAUX_RECYCLEUR) > 0 then begin
       // Il existe des recycleurs
       lRecycleur := TCollectionVaisseauSelInfos.Create;
       lRecycleur.ImportAndCopyList(FCurrVaisseuxList, true);
       lRecycleur.SetVaisseauxAUtiliser(CNT_GID_VAISSEAUX_RECYCLEUR, 1);

       trajetDureeRecycl := mfdgGetDurationTrajet100p(FCurrentPlayer.curPlanete.FLocation, Cible, lRecycleur.GetSpeedUsed, 100, FCurrentPlayer.Conf.UniversSpeedFactorFlotte);

       lRecycleur.Free;

    end else
       trajetDureeRecycl := 0;


    iConsomation := FCurrVaisseuxList.GetConsomationDeut(trajetDistance, trajetDuree);


    lblAttaqueDistance.Caption := sfcFormatStrToMilliers(trajetDistance);
    lblAttaqueTrajetDuree.Caption := ESBDGetDureeStrings(trajetDuree, true);
    lblAttaqueTrajetConsomation.Caption := sfcFormatStrToMilliers(iConsomation);


    if trajetDureeRecycl > 0 then begin
       lblAttaqueTrajetRecycleur.Caption := ESBDGetDureeStrings(trajetDureeRecycl, true);

       if trajetDureeRecycl < trajetDistance then begin
          // les recycleurs vont arriver avant la flotte d'attaque...
          lblAttaqueTrajetRecycleur.Font.Color := clRed;
       end else begin
          lblAttaqueTrajetRecycleur.Font.Color := clWindowText;
       end;

    end else
       lblAttaqueTrajetRecycleur.Caption := '';

    if iConsomation > FCurrentPlayer.curPlanete.FLastRessources.Deuterium then begin
       lblAttaqueTrajetConsomation.Font.Color := clRed;
    end else begin
       lblAttaqueTrajetConsomation.Font.Color := clWindowText;
    end;


    sggUpdateFlotteList(sgGridFlotteList, FCurrentPlayer.cFlotteVaisseaux.FlotteList, FCurrentPlayer);

end;


procedure TfrmRapportHistorique.OpenCdRMonitor;
var xItem: TMenuItem;
    xForm: TformCdRMonitor;
    i, j: integer;
begin


    if FFormCdRMonitorList.Count > 0 then begin
       for i := FFormCdRMonitorList.Count - 1 downto 0 do begin
           xForm := FFormCdRMonitorList.Items[i];

           xItem := xForm.GetMainMenuItem;

           if xItem.Enabled = false then begin
              // on peut le supprimer
              xForm.Free;
              FFormCdRMonitorList.Delete(i);


              menuTopMain.BeginUpdate;

              j := menObservationCdR.IndexOf(xItem);

              if j >= 0 then begin
                 menObservationCdR.Delete(j);
              end;


              menuTopMain.EndUpdate;
           end;


       end;
    end;





    //if FFormCdRMonitor = nil then begin
       xForm := TformCdRMonitor.Create(Self);
    //end;

    xForm.Prepare(FCurrentPlayer, FUnitesInformations);


    menuTopMain.BeginUpdate;


    if menObservationCdR.Count < 2 then begin
       xItem := TMenuItem.Create(menObservationCdR);
       xItem.Caption := '-';
       menObservationCdR.Add(xItem);
    end;



    xItem := TMenuItem.Create(menObservationCdR);
    xItem.Caption := _('En attente...');
    menObservationCdR.Add(xItem);

    xForm.SetMenuItem(xItem);
    FFormCdRMonitorList.Add(xForm);

    menuTopMain.EndUpdate;


end;

procedure TfrmRapportHistorique.cmdCdRObserverClick(Sender: TObject);
begin
   OpenCdRMonitor;
end;

procedure TfrmRapportHistorique.cmdChangePlaneteAndUpdateVaisseauxListClick(Sender: TObject);
label lFinProc;
var pDepart, Cible : TPlanetLocation;
    r, xTotal: integer;
    totalRessource: TOGRessourceAll;
begin
    // Sélectionne la bonne planète, et obtient la liste des vaisseaux


    cmdSondageStopClick(nil);

    cmdAttaqueDoIt.Enabled := false;
    cmdChangePlaneteAndUpdateVaisseauxList.Enabled := false;
    cmdViewAppercuListMsg.Enabled := false;

    pDepart := SpiderGalaxieTextPlaneteToLocation(cbAttaquePlanete.Text);

    FCurrVaisseuxList := nil;

    if pDepart.Galaxie < 1 then begin
       Status(_('Impossible de déterminer la planète choisi'));
       UpdateVaisseaux(sgVaisseaux);
       goto lFinProc;
    end;


    lblStatusAttaque.Font.Color := clBlack;
    lblStatusAttaque.Caption := _('Changement de planète...');
    r := FCurrentPlayer.ChangePlanete(pDepart);

    if r < 0 then begin
       Status(_('Echec de changement de planète'));
       lblStatusAttaque.Font.Color := clRed;
       lblStatusAttaque.Caption := _('Echec changement de planète');
       UpdateVaisseaux(sgVaisseaux);
       goto lFinProc;
    end;

    // si r = 0, la planète était déjà sélectionnée



    if (FCurrentPlayer.cParsing.LastPage.PageType <> prtFlotte1) or (FCurrVaisseuxList = nil) then begin
       // On doit télécharger la page de flotte


       lblStatusAttaque.Caption := _('Téléchargement flotte...');
       r := FCurrentPlayer.RetreiveFlotte1Page;

       if r < 1 then begin
          Status(_('Echec de chargement de la page des vaisseaux'));
          lblStatusAttaque.Font.Color := clRed;
          lblStatusAttaque.Caption := _('Echec');
          UpdateVaisseaux(sgVaisseaux);
          goto lFinProc;
       end;

       lblStatusAttaque.Caption := _('Réussi');

    end;

    if FCurrentPlayer.cFlotteVaisseaux.URLToPost = '' then begin
       lblStatusAttaque2.Caption := _('Flotte max atteint');
       lblStatusAttaque2.Font.Color := clRed;
    end else begin
       lblStatusAttaque2.Caption := '---';
       lblStatusAttaque2.Font.Color := clWindowText;
    end;


    // Récupère le pointeur vers la liste des vaisseaux
    FCurrVaisseuxList := FCurrentPlayer.cFlotteVaisseaux.VaisseauxList;



    if chkAttackWithPT.Checked then begin
       FCurrVaisseuxList.SetVaisseauxAUtiliser(202, FNbPTForCurrentRapport);
    end else
       FCurrVaisseuxList.SetVaisseauxAUtiliser(203, FNbGTForCurrentRapport);

    if chkAttackInclureCroiseur.Checked then begin
       FCurrVaisseuxList.SetVaisseauxAUtiliser(206, seAttackInclureCroiseurs.Value);
    end;

    // met à jour la grille
    UpdateVaisseaux(sgVaisseaux);


    lblAttaqueDeutDisponible.Caption := sfcFormatStrToMilliers(FCurrentPlayer.curPlanete.FLastRessources.Deuterium);
    if FCurrentPlayer.curPlanete.FLastRessources.Deuterium > 1000 then begin
       lblAttaqueDeutDisponible.Font.Color := clWindowText;
    end else begin
       lblAttaqueDeutDisponible.Font.Color := clRed;
    end;



    cbAttaqueSpeedRatio.ItemIndex := 0;


    // met à jour la vitesse, le deutérium
    // MAIS AUSSI la liste des flottes
    UpdateSpeedAndDeutUsed;

    // Evalue le nombre de recycleur necessaire pour recycler sa propre flotte
    //function lGetTotalRessource(VaisseuxList: TCollectionVaisseauSelInfos; UnitesInformations: TCollectionUnitInfos): TOGRessourceAll;

  //  totalRessource := lGetTotalRessource(FCurrVaisseuxList, FUnitesInformations);
    // Calcul les stats
    FCurrVaisseuxList.CalculStats(FUnitesInformations);


    lblNbRecycleurOwnFlotte.Caption  := sfcDivistionResultEnString(FCurrVaisseuxList.RessourceRecyclable, 20000, 2);
    lblRecyclagePointsPerdus.Caption := sfcFormatStrToMilliers(FCurrVaisseuxList.RessourceTotalSum div 1000);
    lblFlotteScore.Caption := sfcFormatStrToMilliers(FCurrVaisseuxList.ScoreFlotte);


lFinProc:
    cmdAttaqueDoIt.Enabled := true;
    cmdChangePlaneteAndUpdateVaisseauxList.Enabled := true;
    cmdViewAppercuListMsg.Enabled := true;

end;

procedure TfrmRapportHistorique.sgVaisseauxDblClickCell(Sender: TObject; ARow,
  ACol: Integer);
var i: integer;
begin

   if (ARow > 0) and (ACol = 2) and (FCurrVaisseuxList <> nil) and (FCurrVaisseuxList.Count > 0) then begin
      i := ARow - 1;

      if (i < 0) or (i >= FCurrVaisseuxList.Count) then
         exit;

      FCurrVaisseauxItem := FCurrVaisseuxList.Items[i];

      // Définit le max dans la colonne quantité
      sgVaisseaux.Cells[1, ARow] :=  IntToStr(FCurrVaisseauxItem.Max);

      ReadVaisseauxQuantite;
      UpdateSpeedAndDeutUsed;
   end;

end;

procedure TfrmRapportHistorique.ReadVaisseauxQuantite;
var r: integer;
    sValue: string;
    iValue: integer;
    cVaisseaux: PVaisseauSelInfos;
begin

    if sgVaisseaux.RowCount < 2 then begin
       Status('ReadVaisseauxQuantite - Pas assez de ligne pour lire les informations de vaisseaux');
       exit;
    end;

    for r := 1 to sgVaisseaux.RowCount - 1 do begin
        sValue := trim(sgVaisseaux.Cells[1, r]);

        iValue := StrToIntDef(sValue, 0);

        cVaisseaux := FCurrVaisseuxList.Items[r - 1];

        if iValue > cVaisseaux.Max then
           iValue := cVaisseaux.Max
        else if iValue < 0 then
           iValue := 0;

        cVaisseaux.QuantiteVoulu := iValue;

    end;

end;

procedure TfrmRapportHistorique.AttaqueLoadStatsCible;
var Cible    : TPlanetLocation;
    peGalaxie: PGalaxiePlanete;
    peStats: PPlayerStats;
    BestPlayer: PPlayerStats;
    peRapport: PRapportHead;
    TotalRessource: integer;
    iDiff, LastDate: int64;
    sStr: string;
begin

    Cible.Galaxie       := seAttaqueGalaxie.Value;
    Cible.SystemSolaire := seAttaqueSystem.Value;
    Cible.Position      := seAttaquePosition.Value;

    peGalaxie := FBase2DonneesPlanete.Get_Pointeur(Cible);

    if peGalaxie <> nil then begin


       lblAttaqueJoueur.Caption := peGalaxie.Joueur;
       lblAttaqueNomPlanete.Caption := peGalaxie.NomPlanete;


       if peGalaxie.Alliance <> '' then begin
          lblAttaqueAlliance.Caption   := peGalaxie.Alliance;

          FCurrentPlayer.StatsPlayer.GetFromAlliance(peGalaxie.Alliance);
          FCurrentPlayer.StatsPlayerFlottes.GetFromAlliance(peGalaxie.Alliance);

          if FCurrentPlayer.StatsPlayer.MaskListResult.Count > 0 then begin
             // Alliance avec son nombre de membre dans les stats générales
             lblAttaqueAlliance.Caption := lblAttaqueAlliance.Caption  + ' (' + IntToStr(FCurrentPlayer.StatsPlayer.MaskListResult.Count) + ' membres)';


             // Meilleur joueur
             BestPlayer := FCurrentPlayer.StatsPlayer.MaskListResult.GetBestPlayer;
             lblAttaqueAllianceBestStats.Caption := sfcFormatStrToMilliers(BestPlayer.Points) + ' points';

             BestPlayer := FCurrentPlayer.StatsPlayerFlottes.MaskListResult.GetBestPlayer;
             if BestPlayer <> nil then
                lblAttaqueAllianceBestStats.Caption := lblAttaqueAllianceBestStats.Caption + ' (' + sfcFormatStrToMilliers(BestPlayer.Points) + ' points)';



             // Moyenne
             lblAttaqueAllianceMoyenne.Caption := sfcFormatStrToMilliers(FCurrentPlayer.StatsPlayer.MaskListResult.GetMoyenneMembre) + ' points (' + sfcFormatStrToMilliers(FCurrentPlayer.StatsPlayerFlottes.MaskListResult.GetMoyenneMembre) + ' points)';

          end else begin
             lblAttaqueAlliance.Caption := lblAttaqueAlliance.Caption  + ' (tous non classé)';
             lblAttaqueAllianceMoyenne.Caption := '---';
             lblAttaqueAllianceBestStats.Caption := '---';

          end;


       end else begin
          peGalaxie.Alliance := '---';
       end;


       peStats := FCurrentPlayer.StatsPlayer.Get_Pointeur(peGalaxie.Joueur);
       if peStats <> nil then
          lblAttaqueStatsGlobales.Caption := sfcFormatStrToMilliers(peStats.Points) + ' points (' + IntToStr(peStats.Place) + ' ième)'
       else
          lblAttaqueStatsGlobales.Caption := _('Non classé');


       peStats := FCurrentPlayer.StatsPlayerFlottes.Get_Pointeur(peGalaxie.Joueur);
       if peStats <> nil then
          lblAttaqueStatsFlottes.Caption := sfcFormatStrToMilliers(peStats.Points) + ' points (' + IntToStr(peStats.Place) + ' ième)'
       else
          lblAttaqueStatsFlottes.Caption := _('Non classé');


          

    end else begin
       lblAttaqueJoueur.Caption     := '---';
       lblAttaqueNomPlanete.Caption := '---';
       lblAttaqueAlliance.Caption   := '---';

       lblAttaqueStatsGlobales.Caption := '---';
       lblAttaqueStatsFlottes.Caption  := '---';

    end;

    peRapport := FBase2DonneesRapports.Get_Pointeur(Cible);
    if peRapport <> nil then begin
       lblAttaqueMetal.Caption := sfcFormatStrToMilliers(peRapport.Ressource.Metal);
       lblAttaqueCristal.Caption := sfcFormatStrToMilliers(peRapport.Ressource.Cristal);
       lblAttaqueDeuterium.Caption := sfcFormatStrToMilliers(peRapport.Ressource.Deuterium);

       TotalRessource := peRapport.Ressource.Metal + peRapport.Ressource.Cristal + peRapport.Ressource.Deuterium;
       lblAttaqueGT.Caption := sfcDivistionResultEnString(TotalRessource div 2, 24500, 2);

       gbAttaqueRapport.Caption := 'Dernier rapport - ' + mbtPlanetLocationToStr(peRapport.PlaneteLocation);;



       LastDate := mrGetMostRecentDate(peRapport.DateLastEspionnage);
       iDiff := DateTimeToUnix(Now) - LastDate;
       if iDiff < 2 then
          sStr := '1 sec.'
       else
          sStr := ESBDGetDureeStrings(iDiff, false, 3);
       lblAttaqueValidite.Caption := sStr;

       if scDefense in peRapport.SectionConnu then
          lblAttaqueDefense.Caption := sfcFormatStrToMilliers(peRapport.NbDefense)
       else
          lblAttaqueDefense.Caption := _('Inconnu');

          
       if scFlotte in peRapport.SectionConnu then
          lblAttaqueFlotte.Caption  := sfcFormatStrToMilliers(peRapport.NbFlotte)
       else
          lblAttaqueFlotte.Caption := _('Inconnu');




    end else begin
       lblAttaqueMetal.Caption := '---';
       lblAttaqueCristal.Caption := '---';
       lblAttaqueDeuterium.Caption := '---';
       lblAttaqueGT.Caption := '---';
       lblAttaqueValidite.Caption := '---';

       gbAttaqueRapport.Caption := _('Dernier rapport');

       lblAttaqueDefense.Caption := '---';
       lblAttaqueFlotte.Caption := '---';

    end;




end;


procedure TfrmRapportHistorique.Button3Click(Sender: TObject);
begin
    formOGSExport.DoShow(FCurrentPlayer, FBase2DonneesPlanete, FBase2DonneesRapports);
end;

procedure TfrmRapportHistorique.cmdAttaqueDoItClick(Sender: TObject);
label lRetry, lFinProc;
var Cible, pDepart: TPlanetLocation;
    Res: TFlotteEnvoiRes;
    iRetry, r: integer;
    peRapport: PRapportHead;
    iSpeedRatio: integer;

begin
    ReadVaisseauxQuantite;

    if FCurrVaisseuxList.DoExistVaisseauxAEnvoyer  = false then begin
       // aucun vaisseaux choisis
       Status(_('Aucun vaisseaux à envoyer...'));
       exit;
    end;

    Cible.Galaxie       := seAttaqueGalaxie.Value;
    Cible.SystemSolaire := seAttaqueSystem.Value;
    Cible.Position      := seAttaquePosition.Value;

    if (Cible.Galaxie < 1) then begin
       lblStatusAttaque.Caption := _('Cible invalide');
       exit;
    end;

    pDepart := SpiderGalaxieTextPlaneteToLocation(cbAttaquePlanete.Text);

    if chkDisableSecuSondage.Checked = false then begin
       if pDepart.Galaxie <> Cible.Galaxie then begin
          lblStatusAttaque.Font.Color := clRed;
          lblStatusAttaque.Caption := _('Attaque dans galaxie différente (sécurité)');
          exit;
       end;
    end;

    cmdAttaqueDoIt.Enabled := false;
    cmdChangePlaneteAndUpdateVaisseauxList.Enabled := false;
    cmdViewAppercuListMsg.Enabled := false;

    iRetry := 0;

    if FCurrentPlayer.cParsing.LastPage.PageType <> prtFlotte1 then begin
       // On a du télécharger d'autre page entre temps (comme la page d'aperçu pour
       // vérifier les flottes envoyées)

       // On doit donc télécharger la page de flotte 1
       // Mais dans ce cas là, la liste des vaisseaux (et leur choix sera perdu...)

    end;



    // sauvegarde l'indice de la planète
    FCurrentPlayer.Conf.AttackLastPlanete := cbAttaquePlanete.ItemIndex;

    Status('-------------');
    
    lblStatusAttaque.Font.Color := clGreen;
    lblStatusAttaque.Caption := _('Envoi des vaisseaux');

    if cbAttaqueSpeedRatio.ItemIndex < 0 then
       cbAttaqueSpeedRatio.ItemIndex := 0;
    iSpeedRatio := 10 - cbAttaqueSpeedRatio.ItemIndex;


lRetry:
    Res := FCurrentPlayer.ProceedAttaque(Cible, iSpeedRatio, chkAttaqueLune.Checked);
    Inc(iRetry);


    lblStatusAttaque.Font.Color := clRed;
    case Res of
        ferFatalError: begin
                           lblStatusAttaque.Caption := _('Erreur');
                           seAttaqueGalaxie.Value := -1;
                       end;
        ferSocketError: begin
                           lblStatusAttaque.Caption := _('Erreur de socket');
                       end;


        ferShouldRetry: begin
                           if iRetry > 1 then begin
                              lblStatusAttaque.Caption := _('Erreur (Should retry)');
                              seAttaqueGalaxie.Value := -1;
                           end else begin
                              lblStatusAttaque.Caption := _('Erreur, réessaye...');
                              goto lRetry;
                           end;

                       end;

        ferSuccess: begin
                           FCurrDate := DateTimeToUnix(Now);

                           peRapport := FBase2DonneesRapports.Get_Pointeur(Cible);

                           if peRapport = nil then begin
                              // on attaque une cible qui n'a jamais exiter
                              // par exemple à partir du menu galaxie
                              peRapport := FBase2DonneesRapports.AddUnknowFromCoord(Cible);
                           end;

                            if mrInjectOnlyIfNeed(peRapport.DateLastAttaque, FCurrDate) then begin
                               Status('Nombre d''attaque mis à jour - ' + mbtPlanetLocationToStr(Cible));
                               peRapport.NbAttack := peRapport.NbAttack + 1;
                               peRapport.bShouldBeUpdateFixed := true;

                               if FCurrentRapport = peRapport then begin
                                  seNbAttaque.Value := peRapport.NbAttack;
                                  cmdUpdatePlaneteClick(nil);
                               end else begin
                                  RefreshRapportLignes(peRapport);
                               end;
                            end;

                           lblStatusAttaque.Caption := 'Envoyé ' + mbtPlanetLocationToStr(Cible);
                           lblStatusAttaque.Font.Color := clBlue;
                           seAttaqueGalaxie.Value := -1;

                           FNbGTForCurrentRapport := 0;
                           
                           r := FCurrentPlayer.RetreiveFlotte1Page;

                           if r < 1 then begin
                               Status(_('Echec de chargement de la page des vaisseaux'));
                               FCurrVaisseuxList := nil;
                               UpdateVaisseaux(sgVaisseaux);
                               goto lFinProc;
                           end;

                           if FCurrentPlayer.cFlotteVaisseaux.URLToPost = '' then begin
                              lblStatusAttaque2.Caption := _('Flotte max atteint');
                              lblStatusAttaque2.Font.Color := clRed;
                           end else begin
                              lblStatusAttaque2.Caption := '---';
                              lblStatusAttaque2.Font.Color := clWindowText;
                           end;

                           sggUpdateFlotteList(sgGridFlotteList, FCurrentPlayer.cFlotteVaisseaux.FlotteList, FCurrentPlayer);
                           

                           FCurrVaisseuxList := FCurrentPlayer.cFlotteVaisseaux.VaisseauxList;
                           UpdateVaisseaux(sgVaisseaux);


                    end;

        ferNoVaisseaux: begin
                           lblStatusAttaque.Caption := _('Pas de vaisseaux');
                           seAttaqueGalaxie.Value := -1;
                       end;

        ferFlotteMaxAtteinte: begin
                           lblStatusAttaque.Caption := _('Flotte Max atteint');
                           seAttaqueGalaxie.Value := -1;
                       end;

        ferPlaneteInvalid: begin
                           if FCurrentPlayer.cParsing.pFlotte4.IsPlaneteVide then
                              lblStatusAttaque.Caption := 'Planète non habitée - ' + mbtPlanetLocationToStr(Cible)
                           else if FCurrentPlayer.cParsing.pFlotte4.IsPlaneteProtectNoob then
                              lblStatusAttaque.Caption := 'Protection des newbz - ' + mbtPlanetLocationToStr(Cible)
                           else if FCurrentPlayer.cParsing.pFlotte4.IsPlaneteModeVacance then
                              lblStatusAttaque.Caption := 'Mode vacances - ' + mbtPlanetLocationToStr(Cible)
                           else if FCurrentPlayer.cParsing.pFlotte4.IsPlaneteCantBeAccessible then
                              lblStatusAttaque.Caption := 'Planète invalide - ' + mbtPlanetLocationToStr(Cible);

                           seAttaqueGalaxie.Value := -1;
                       end;



    end;


    lblAttaqueDeutDisponible.Caption := sfcFormatStrToMilliers(FCurrentPlayer.curPlanete.FLastRessources.Deuterium);


lFinProc:
    cmdAttaqueDoIt.Enabled := true;
    cmdChangePlaneteAndUpdateVaisseauxList.Enabled := true;
    cmdViewAppercuListMsg.Enabled := true;
end;


procedure TfrmRapportHistorique.seAttaqueGalaxieChange(Sender: TObject);
begin
     AttaqueLoadStatsCible;
     UpdateSpeedAndDeutUsed;
end;

procedure TfrmRapportHistorique.seAttaqueSystemChange(Sender: TObject);
begin
    AttaqueLoadStatsCible;
    UpdateSpeedAndDeutUsed;
end;

procedure TfrmRapportHistorique.seAttaquePositionChange(Sender: TObject);
begin
     AttaqueLoadStatsCible;
     UpdateSpeedAndDeutUsed;
end;

procedure TfrmRapportHistorique.menEspionnerClick(Sender: TObject);
begin
    SondageCurrentSelPlaneteInGridList;
end;


procedure TfrmRapportHistorique.SondageLockCmd(Valeur: boolean);
begin

   cmdSondageInactifs.Enabled := Valeur;
   gbSondagePoints.Enabled    := Valeur;
   cmdSondagePoints.Enabled   := Valeur;

   cmdSondageJoueur.Enabled   := Valeur;
   cmdSondageAlliance.Enabled := Valeur;
   
end;


function TfrmRapportHistorique.SondageGetPointsVerification(Joueur: string): boolean;
var peStats: PPlayerStats;
    bCondFlotteOk: boolean;
begin


    // Vérifie les points globaux
    Result  := false;
    peStats := FCurrentPlayer.StatsPlayer.Get_Pointeur(Joueur);

    if peStats = nil then begin
       if chkSondagePointGlobalNonClasse.Checked then begin
          // On prend en compte les non classé
          Result := true;
       end;

    end else begin
       if peStats.Points < seSondageStatsLimitGlobales.Value then begin
          // Le joueur a peu de points
          Result := true;
       end;
    end;


    if Result and optAttaqueOR.Checked then begin
       // C'est un OU
       // et la première condition est vrai
       // -> Pas besoin de calculer la seconde condition
       exit;

    end else if (Result = false) and (optAttaqueOR.Checked = false) then begin
       // C'est un ET
       // et la première condition est fausse
       // -> Inutile de calculer la seconde
       exit;

    end else begin
       // C'est soit un ET, soit un OU
       // et dans les deux cas on a besoin de connaitre l'évaluation de
       // la seconde condition
       // Ce qui signifie que si la seconde est vrai, on pourra l'ajouter
       // sans se soucier de l'opérateur

       // On calcul la seconde condition
       Result := false;
       bCondFlotteOk := false;
       peStats := FCurrentPlayer.StatsPlayerFlottes.Get_Pointeur(Joueur);

       if peStats = nil then begin
          if chkSondagePointFlottesNonClasse.Checked then begin
             // On prend en compte les non classé
             bCondFlotteOk := true;
          end;

       end else begin
          if peStats.Points < seSondageStatsLimitFlottes.Value then begin
             // Le joueur a peu de points
             bCondFlotteOk := true;
          end;

       end;

       if bCondFlotteOk then
          Result := true;

    end;

end;


procedure TfrmRapportHistorique.cmdSondagePointsClick(Sender: TObject);
label lAddLune;
var peGalaxie: PGalaxiePlanete;
    Coord, nTmp: TPlanetLocation;
    iPosition: integer;
    iSystem: integer;
    Duree: int64;

    NbAjoute: integer;
  //  peStats: PPlayerStats;

  //  bCondGlobaleOk: boolean;
  //  bCondFlotteOk : boolean;
begin

       if FInfosBaseDeDonneCharge = false then begin
          // aucune base de données chargées...
          Status(_('Aucune base de données chargée'));
          exit;
       end;

   SondageLockCmd(false);

   if seSondageSystemEnd.Value < seSondageSystemStart.Value then begin
      iSystem := seSondageSystemEnd.Value;
      seSondageSystemEnd.Value := seSondageSystemStart.Value;
      seSondageSystemStart.Value := iSystem;
   end;


   FCurrDate := DateTimeToUnix(Now);
   NbAjoute := 0;

   Coord.Galaxie := FBase2DonneesPlanete.Galaxie;

   for iSystem := seSondageSystemStart.Value to seSondageSystemEnd.Value do begin

       Coord.SystemSolaire := iSystem;

       for iPosition := 1 to  15 do begin
           Coord.Position := iPosition;

           peGalaxie := FBase2DonneesPlanete.Get_Pointeur(Coord);

           if (peGalaxie <> nil)  then begin
              Duree := FCurrDate - peGalaxie.Date;

              if Duree <= seSondageDureePourEtrePrisEnCompte.Value then begin

                 if (peGalaxie.Joueur = '') or (sfcFlagsIsIn(CNT_GALAXIE_FLAGS_ASTEROIDES, peGalaxie.Flags)) then begin
                   // Planète non habité

                 end else begin

                    if chkSondageStatsExclureInactif.Checked then begin

                       if (sfcFlagsIsIn(CNT_GALAXIE_FLAGS_INACTIF_2SEMAINES, peGalaxie.Flags)) or (sfcFlagsIsIn(CNT_GALAXIE_FLAGS_INACTIF_4SEMAINES, peGalaxie.Flags)) then begin
                          // On ne le sonde pas
                          if chkSondageMsgDebug.Checked then
                             Status('Sondage - Inactif non pris en compte: ' + mbtPlanetLocationToStr(peGalaxie.Location));
                          Continue;
                       end;

                    end;


                    if SondageGetPointsVerification(peGalaxie.Joueur) then begin
                       // le joueur vérifie les conditions d'ajout au niveau de ses points



                        if chkSondageAddOnlyLune.Checked = false then begin
                           if SondageCheckAndTryToAddThisCoord(Coord, peGalaxie, false) then begin
                              Inc(NbAjoute);
                           end;
                        end else begin
                           goto lAddLune;
                        end;


                        if chkSondageInclureLune.Checked then begin
lAddLune:
                           if peGalaxie.Lune.Surface > 0 then begin
                              // la planète possède une lune

                              nTmp := Coord;
                              nTmp.Position := nTmp.Position + CNT_POSITION_LUNE;
                              if SondageCheckAndTryToAddThisCoord(nTmp, peGalaxie, false) then begin
                                 Inc(NbAjoute);
                              end;
                           end;

                        end;

                    end;

                    (*
                    // Vérifie les points globaux
                    bCondGlobaleOk := false;
                    peStats := FStatsPlayer.Get_Pointeur(peGalaxie.Joueur);

                    if peStats = nil then begin
                       if chkSondagePointGlobalNonClasse.Checked then begin
                          // On prend en compte les non classé
                          bCondGlobaleOk := true;
                       end;

                    end else begin
                       if peStats.Points < seSondageStatsLimitGlobales.Value then begin
                          // Le joueur a peu de points
                          bCondGlobaleOk := true;
                       end;
                    end;

                    if bCondGlobaleOk and optAttaqueOR.Checked then begin
                       // C'est un OU
                       // et la première condition est vrai
                       // -> Pas besoin de calculer la seconde condition

                       if SondageCheckAndTryToAddThisCoord(Coord, peGalaxie, false) then
                          Inc(NbAjoute);


                    end else if (bCondGlobaleOk = false) and (optAttaqueOR.Checked = false) then begin
                       // C'est un ET
                       // et la première condition est fausse
                       // -> Inutile de calculer la seconde

                    end else begin
                       // C'est soit un ET, soit un OU
                       // et dans les deux cas on a besoin de connaitre l'évaluation de
                       // la seconde condition
                       // Ce qui signifie que si la seconde est vrai, on pourra l'ajouter
                       // sans se soucier de l'opérateur

                       // On calcul la seconde condition
                       bCondFlotteOk := false;
                       peStats := FStatsPlayerFlottes.Get_Pointeur(peGalaxie.Joueur);

                       if peStats = nil then begin
                          if chkSondagePointFlottesNonClasse.Checked then begin
                             // On prend en compte les non classé
                             bCondFlotteOk := true;
                          end;

                       end else begin
                          if peStats.Points < seSondageStatsLimitFlottes.Value then begin
                             // Le joueur a peu de points
                             bCondFlotteOk := true;
                          end;

                       end;

                       if bCondFlotteOk then begin
                          if SondageCheckAndTryToAddThisCoord(Coord, peGalaxie, false) then
                             Inc(NbAjoute);

                       end;

                    end;
                    *)

                 end;

              end else begin
                 Status('Sondage - Non pris en compte car trop ancien: ' + mbtPlanetLocationToStr(peGalaxie.Location));

              end;

           end else begin
              Status('Sondage - Non scanné: ' + mbtPlanetLocationToStr(Coord));

           end;

       end;

   end;

   Status('Sondage - Total ajouté: ' + IntToStr(NbAjoute));

   SondageLockCmd(true);

end;

procedure TfrmRapportHistorique.cmdVerifierConnexionClick(Sender: TObject);
begin
    cmdVerifierConnexion.Enabled := false;

    if suConnecterSurInternetResolveMethod then begin
       Status(_('Etat connexion DNS: Connecté'));
    end else begin
       Status(_('Etat connexion DNS: Non Connecté'));
    end;

    if cdtConnecterSurInternetAPI then begin
       Status(_('Etat connexion API: Connecté'));
    end else begin
       Status(_('Etat connexion API: Non Connecté'));
    end;


    cmdVerifierConnexion.Enabled := true;
end;

procedure TfrmRapportHistorique.cmdViewAppercuListMsgClick(Sender: TObject);
var r: integer;
    cMsgList: TCollectionAppMessage;
    peMsg: PAppMessage;
begin
    cmdAttaqueDoIt.Enabled := false;
    cmdChangePlaneteAndUpdateVaisseauxList.Enabled := false;
    cmdViewAppercuListMsg.Enabled := false;


    r := FCurrentPlayer.ProceedUpdateApercu;

    cMsgList := FCurrentPlayer.cParsing.pApercu.MsgList;


    if cMsgList.Count > 0 then begin
       for  r := 0 to cMsgList.Count - 1 do begin
           peMsg := cMsgList.Items[r];

           Status(peMsg.Msg);
       end;

    end else begin
        Status(_('Aucun message'));
    end;

    
    //UpdateMsgList(sgGridMsgList, cMsgList);

    cmdAttaqueDoIt.Enabled := true;
    cmdChangePlaneteAndUpdateVaisseauxList.Enabled := true;
    cmdViewAppercuListMsg.Enabled := true;

end;

procedure TfrmRapportHistorique.seSondageStatsLimitGlobalesChange(
  Sender: TObject);
begin
    FCurrentPlayer.Conf.SondageLimitStatsGlobal := seSondageStatsLimitGlobales.Value;
end;

procedure TfrmRapportHistorique.seSondageStatsLimitFlottesChange(
  Sender: TObject);
begin
    FCurrentPlayer.Conf.SondageLimitStatsFlottes := seSondageStatsLimitFlottes.Value;
end;

procedure TfrmRapportHistorique.chkSondagePointGlobalNonClasseClick(
  Sender: TObject);
begin
    FCurrentPlayer.Conf.SondageLimitStatsGlobalInclureNonClasse := chkSondagePointGlobalNonClasse.Checked;
end;

procedure TfrmRapportHistorique.chkSondagePointFlottesNonClasseClick(
  Sender: TObject);
begin
    FCurrentPlayer.Conf.SondageLimitStatsFlottesInclureNonClasse := chkSondagePointFlottesNonClasse.Checked;
end;

procedure TfrmRapportHistorique.gdSystemSolaireClickCell(Sender: TObject; ARow,
  ACol: Integer);
var i: integer;
    peRapport: PRapportHead;
begin

    i := ARow - 1;

    if (i < 0) or (i >= FCurrSystemSolaire.Count) then exit;

    FCurrentSystemSolaire := FCurrSystemSolaire.Items[i];
    peRapport := FBaseCurrSystemSolaire.Get_Pointeur(FCurrentSystemSolaire.Location);  // peGalaxie.Location;

    if peRapport <> nil then begin
       FCurrentRapport := peRapport;
       LoadCurrentInForm;
       
    end else begin
       FCurrentRapport := nil;
       InitForm;
    end;



end;

procedure TfrmRapportHistorique.menFlagGalaxieXXXInclClick(Sender: TObject);
var m: TMenuItem;
begin
    if Sender <> nil then begin
       m := TMenuItem(Sender);

       sfcFlagsAdd(m.Tag, FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu);
       sfcFlagsDel(m.Tag, FCurrentPlayer.Conf.FiltreFlagsGalaxieExclu);
       RefreshMenuFiltreCheckbox;
    end;
    
end;

procedure TfrmRapportHistorique.menFlagGalaxieYYYExclClick(Sender: TObject);
var m: TMenuItem;
begin
    if Sender <> nil then begin
       m := TMenuItem(Sender);

       sfcFlagsAdd(m.Tag, FCurrentPlayer.Conf.FiltreFlagsGalaxieExclu);
       sfcFlagsDel(m.Tag, FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu);
       RefreshMenuFiltreCheckbox;
    end;

end;

procedure TfrmRapportHistorique.menFlagGalaxieZZZIgnoreClick(Sender: TObject);
var m: TMenuItem;
begin
    if Sender <> nil then begin
       m := TMenuItem(Sender);

       sfcFlagsDel(m.Tag, FCurrentPlayer.Conf.FiltreFlagsGalaxieExclu);
       sfcFlagsDel(m.Tag, FCurrentPlayer.Conf.FiltreFlagsGalaxieInclu);
       RefreshMenuFiltreCheckbox;
    end;

end;



procedure TfrmRapportHistorique.menFlagXXXInclClick(Sender: TObject);
var m: TMenuItem;
begin
    if Sender <> nil then begin
       m := TMenuItem(Sender);

       sfcFlagsAdd(m.Tag, FCurrentPlayer.Conf.FiltreFlagsRapportInclu);
       sfcFlagsDel(m.Tag, FCurrentPlayer.Conf.FiltreFlagsRapportExclu);
       RefreshMenuFiltreCheckbox;
    end;

end;

procedure TfrmRapportHistorique.menFlagYYYExclClick(Sender: TObject);
var m: TMenuItem;
begin
    if Sender <> nil then begin
       m := TMenuItem(Sender);

       sfcFlagsAdd(m.Tag, FCurrentPlayer.Conf.FiltreFlagsRapportExclu);
       sfcFlagsDel(m.Tag, FCurrentPlayer.Conf.FiltreFlagsRapportInclu);
       RefreshMenuFiltreCheckbox;
    end;
end;

procedure TfrmRapportHistorique.menFlagZZZIgnoreClick(Sender: TObject);
var m: TMenuItem;
begin
    if Sender <> nil then begin
       m := TMenuItem(Sender);

       sfcFlagsDel(m.Tag, FCurrentPlayer.Conf.FiltreFlagsRapportExclu);
       sfcFlagsDel(m.Tag, FCurrentPlayer.Conf.FiltreFlagsRapportInclu);
       RefreshMenuFiltreCheckbox;
    end;
end;

procedure TfrmRapportHistorique.menFlotteListRetourClick(Sender: TObject);
var pe: PFlotteListEnVoyage;
    peFlotteUID: TFlotteOwnUID;
begin

    if FLastIndexSelectFlotteList < FCurrentPlayer.cFlotteVaisseaux.FlotteList.Count then begin
       pe := FCurrentPlayer.cFlotteVaisseaux.FlotteList.Items[FLastIndexSelectFlotteList];

       peFlotteUID.DateDepart := pe.DepartDate;
       peFlotteUID.Location   := pe.HashDepartArrivee;

       if cmdChangePlaneteAndUpdateVaisseauxList.Enabled then begin
          FCurrentPlayer.ProceedReturnFlotte(@peFlotteUID);
          cmdChangePlaneteAndUpdateVaisseauxListClick(nil);
       end;

       
    end else begin
    
    end;

end;

procedure TfrmRapportHistorique.menFiltreTousElementPresentClick(
  Sender: TObject);
begin
    FCurrentPlayer.Conf.FiltrePresenceTousDefaut := true;
    RefreshMenuFiltreCheckbox;
end;

procedure TfrmRapportHistorique.menFiltreTousElementNonPresentClick(
  Sender: TObject);
begin
    FCurrentPlayer.Conf.FiltrePresenceTousDefaut := false;
    RefreshMenuFiltreCheckbox;
end;

procedure TfrmRapportHistorique.menFlagAucunInclClick(Sender: TObject);
begin
    FCurrentPlayer.Conf.FiltreFlagsAucunRapportInclu := true;
    RefreshMenuFiltreCheckbox;
end;

procedure TfrmRapportHistorique.menFlagAucunExclClick(Sender: TObject);
begin
    FCurrentPlayer.Conf.FiltreFlagsAucunRapportInclu := false;
    RefreshMenuFiltreCheckbox;
end;

procedure TfrmRapportHistorique.menFiltreToutesConditionsRempliesClick(
  Sender: TObject);
begin
    FCurrentPlayer.Conf.FiltreInclusionMethodAllVerif := true;
    RefreshMenuFiltreCheckbox;
end;

procedure TfrmRapportHistorique.menFiltreAuMoinsUneCondRemplieClick(
  Sender: TObject);
begin
    FCurrentPlayer.Conf.FiltreInclusionMethodAllVerif := false;
    RefreshMenuFiltreCheckbox;
end;

procedure TfrmRapportHistorique.sgFiltrerClickCell(Sender: TObject; ARow,
  ACol: Integer);
var i: integer;
begin

    // gbPlanete
    i := ARow - 1;

    if (i < 0) or (i >= FBaseFiltree.Count) then exit;

    FCurrentRapport := FBaseFiltree.Items[i];
    FRowCurrentRapport := ARow;
    LoadCurrentInForm;
end;


procedure TfrmRapportHistorique.sgGridFlotteListClickCell(Sender: TObject; ARow,
  ACol: Integer);
var pe: PFlotteListEnVoyage;
begin
    FLastIndexSelectFlotteList := ARow;


    Dec(FLastIndexSelectFlotteList);

    if (FLastIndexSelectFlotteList < FCurrentPlayer.cFlotteVaisseaux.FlotteList.Count) and (FLastIndexSelectFlotteList >= 0) then begin
       pe := FCurrentPlayer.cFlotteVaisseaux.FlotteList.Items[FLastIndexSelectFlotteList];

       memFlotteListCoord.Caption     := mbtPlanetLocationToStr(pe.Arrivee);


       if pe.Direction = odAller then begin
          menFlotteListRetour.Enabled := true;

       end else begin
          menFlotteListRetour.Enabled := false;

       end;

       memFlotteListEspionner.Enabled := true;

    end else begin
       memFlotteListCoord.Caption := '(aucun)';
       memFlotteListEspionner.Enabled := false;
       menFlotteListRetour.Enabled    := false;
    end;


    
end;

procedure TfrmRapportHistorique.sgListeAttaqueClickCell(Sender: TObject; ARow,
  ACol: Integer);
var i: integer;
    pe: PLAItem;
    xCible: TPlanetLocation;
    peRapport: PRapportHead;
begin

    if (FCurrentPlayer = nil) or (FCurrentPlayer.cListeDattaque = nil) then begin
       exit;
    end;

    i := ARow - 1;

    if (i < 0) or (i >= FCurrentPlayer.cListeDattaque.Count) then exit;

    pe := FCurrentPlayer.cListeDattaque.Items[i];
    FCurrentIndiceListAttackSel := i;

    xCible := pe.Operation.Cible;
    if pe.Operation.CibleType = ctLune then begin
       xCible.Position := xCible.Position + CNT_POSITION_LUNE;
    end;

    peRapport := FBase2DonneesRapports.Get_Pointeur(xCible);

    if peRapport <> nil then begin
       FCurrentRapport := peRapport;
       FRowCurrentRapport := -1;
       LoadCurrentInForm;
    end;

end;

procedure TfrmRapportHistorique.sgListeAttaqueDblClickCell(Sender: TObject;
  ARow, ACol: Integer);
var i: integer;
    pe: PLAItem;
begin

    if (FCurrentPlayer = nil) or (FCurrentPlayer.cListeDattaque = nil) then begin
       exit;
    end;

    i := ARow - 1;

    if (i < 0) or (i >= FCurrentPlayer.cListeDattaque.Count) then exit;

    pe := FCurrentPlayer.cListeDattaque.Items[i];

    formVaisseauxEdit.GidToStr := FCurrentPlayer.GidToStr;
    formVaisseauxEdit.EditVaisseaux(@pe.Vaisseaux);

    cmdListeAttaqueUpdateListClick(nil);

end;

procedure TfrmRapportHistorique.menFiltreTirerParGTClick(Sender: TObject);
begin
    FBaseFiltree.TrieParGT;
    UpdateAllSpec(sgFiltrer, FBaseFiltree);
end;

procedure TfrmRapportHistorique.menFiltreTrierParDateClick(Sender: TObject);
begin
    FBaseFiltree.TrieDuree;
    UpdateAllSpec(sgFiltrer, FBaseFiltree);
end;

procedure TfrmRapportHistorique.html1Click(Sender: TObject);
begin
    sgFiltrer.SaveToHTML('d:\test.html');
end;


function IsDebugged: integer; stdcall;
asm
    push ebx
    mov  eax, $18
    push DWORD PTR FS:[eax]
    pop ebx
    MOV    EAX, DWORD PTR DS:[ebx+ $30]
    MOVZX  EAX, BYTE PTR DS:[EAX+ $2]
    pop ebx

(*
00444161    64:A1 18000000  MOV     EAX, DWORD PTR FS:[18]     ; eax = début du segment FS: Thread Environment Block
00444167    8B40 30         MOV     EAX, DWORD PTR DS:[EAX+30] ; eax = PEB adresse
0044416A    0FB640 02       MOVZX   EAX, BYTE PTR DS:[EAX+2]   ; eax = BeingDebugged (champ Boolean du PEB)
*)

end;

procedure TfrmRapportHistorique.timLoadLastDBAutoTimer(Sender: TObject);
label lShutdown;
var xVarBool: boolean;
    sParam: string;
    lSecu: integer;

{$IFDEF AUTH_FILE_USE}
    security: TLicenceKeyChecking;
{$ENDIF}
begin
    //Status('Loading Last DB');
    
    timLoadLastDBAuto.Interval := 0;

    if FLocalSetting.ConfLoadTheLastestBDOnProfilLoad <> 0 then begin
       if cmdLoadDBFromProfils.Enabled then begin
          cmdLoadDBFromProfilsClick(nil);
       end;

    end;

    if FQuitDirect then begin
       exit;
    end;

    if timLoadLastDBAuto.Interval > 3600 then begin
lShutdown:

          exit;
    end;




    //Status('Loading Last DB end');

    sParam := lowercase(ParamStr(1));
    if pos('autologin', sParam) > 0 then begin
       // fait le login ?
       Status('Login start up');
       SpiderDoLogin;
    end;
    xVarBool := true;

    
{$IFDEF AUTH_FILE_USE}
    if FLicenceKeyMemory = nil then begin
       // Erreur...
       goto lShutdown;
       
    end else begin
       security := TLicenceKeyChecking.Create;
       security.LoadFromStream(FLicenceKeyMemory);

       // calcul pour embrouiller les crackeurs
       msgInitDistanceColor;



       if FAuthAProposDone = false then begin
          security.DecryptData(true);

          FAuthCaption := security.formCaption;

          Memo4.Lines.Add('------------');
          Memo4.Lines.Add(security.formAPropos);
          Memo4.Lines.Add('');

          if FCurrentPlayer.Conf.Univers > 0 then begin
             Caption := APP_CAPTION + format(_(' - Univers %d'), [FCurrentPlayer.Conf.Univers]) + ' [v' + CNT_CURR_VERSION + '] ' + FAuthCaption;
          end;

          if (security.AccessLevel < CNT_ACCESS_LEVEL_OFFICIER) then begin
             FCurrentPlayer.AllowToWorkWithOfficier := false;
          end else begin
             FCurrentPlayer.AllowToWorkWithOfficier := true;
          end;


          FAuthAProposDone := true;
       end;

       if security.IsValidFile = false then begin
          bDoExpiration := security.hash;
       end;
       //security.DecryptData;

       security.Free;
       FLicenceKeyMemory.Seek(0, soBeginning);
    end;

    if xVarBool = false then begin
       goto lShutdown;
    end;


{$ENDIF}

end;

procedure TfrmRapportHistorique.Services_Commande20_VoirMsgStatus(Socket: TBotServicesClient);
var sSend : string;
    i, j: integer;
begin

   if txtDebug1.Lines.Count = 0 then begin
      sSend := 'Aucun message';
      Socket.SendStr(sSend + CNT_CRLF);
      exit;

   end else begin
      sSend := 'Messages:<br><br>';
      Socket.SendStr(sSend + CNT_CRLF);

      if txtDebug1.Lines.Count < 40 then begin
         j := 0;
      end else begin
         j := txtDebug1.Lines.Count - 40;
      end;

      for i := j to txtDebug1.Lines.Count - 1 do begin
         sSend := txtDebug1.Lines.Strings[i];
         Socket.SendStr(sSend + '<br>' + CNT_CRLF);

      end;
      
   end;

   sSend := '<br><br>Terminé<br>';
   Socket.SendStr(sSend + CNT_CRLF);
end;

procedure TfrmRapportHistorique.Services_Commande15_SpiderLireMsg(Socket: TBotServicesClient);
var sSend : string;
begin


    if cmdMessageListGet.Enabled = true then begin
       // Ok, on peut lire les messages
       sSend := 'Lecture des messages';
       FServiceDelayCmd := SERVICES_CMD_SPIDER_READMSG;

    end else if cmdSondageStop.Enabled = true then begin
       // Boucle de sondage en cours, on l'arrête
       sSend := 'Arrêt de la boucle d''envoi, et lecture des messages';
       cmdSondageStopClick(nil);
       FServiceDelayCmd := SERVICES_CMD_SPIDER_READMSG;

    end else begin
       sSend := 'Impossible de lire les messages (Pas loggé ou autre opération en cours)';
    end;

    Socket.SendStr(sSend + CNT_CRLF);
    
end;


procedure TfrmRapportHistorique.Services_Commande11_SpiderScan(Socket: TBotServicesClient; Params: string);
var systStart, systEnd, iPlaneteUse, iDureeAncien: integer;
    iSondeAfter: integer;
    sSend : string;
begin

    if NoT(Services_ExtractIntegerParams(Params, systStart, systEnd, iPlaneteUse, iDureeAncien, iSondeAfter)) then begin
       sSend := 'Paramètres invalides (c1)';
       Socket.SendStr(sSend + CNT_CRLF);
       exit;
    end;

    if (systStart < 1) or (systStart > 499) or
       (systEnd < 1) or (systEnd > 499) or
       (iPlaneteUse < 0) or (iPlaneteUse > cbGalaxieScanPlanete.Items.Count - 1) then begin

       sSend := 'Paramètres invalides (c2)';
       Socket.SendStr(sSend + CNT_CRLF);
       exit;
    end;

    if iDureeAncien < 1 then
       iDureeAncien := 60;


    seGalaxieSystemeStart.Value := systStart;
    seGalaxieSystemeEnd.Value := systEnd;
    cbGalaxieScanPlanete.ItemIndex := iPlaneteUse;
    seSpiderGalaxieDureeRecent.Value := iDureeAncien;

    if iSondeAfter > 0 then begin
       Status('Sondage après le scan');
       seSondageSystemStart.Value := systStart;
       seSondageSystemEnd.Value := systEnd;
       cbSondagePlanete.ItemIndex := iPlaneteUse;
       seSondageDureePourEtrePrisEnCompte.Value := iDureeAncien;

       // On les sondes tous, donc une faible durée
       seSondageIgnoreDelayLastSondage.Value := 600;

       chkSonderEnsuiteLesInactifs.Checked := true;
    end else begin
       chkSonderEnsuiteLesInactifs.Checked := false;
    end;

    if cmdSpiderGalaxieScan.Enabled = false then begin
       sSend := 'Impossible de scanner (Pas loggé ou autre opération en cours)';
    end else begin
       FServiceDelayCmd := SERVICES_CMD_SPIDER_SCAN;
       sSend := 'Scan en cours';
    end;

    Socket.SendStr(sSend + CNT_CRLF);

end;


procedure TfrmRapportHistorique.Services_Commande12_SpiderSondage(Socket: TBotServicesClient; Params: string);
var systStart, systEnd, iPlaneteUse, iDureeAncien: integer;
    iDureeRecent: integer;
    sSend : string;
begin

    if NoT(Services_ExtractIntegerParams(Params, systStart, systEnd, iPlaneteUse, iDureeAncien, iDureeRecent)) then begin
       sSend := 'Paramètres invalides';
       Socket.SendStr(sSend + CNT_CRLF);
       exit;
    end;

    if (systStart < 1) or (systStart > 499) or
       (systEnd < 1) or (systEnd > 499) or
       (iPlaneteUse < 0) or (iPlaneteUse > cbGalaxieScanPlanete.Items.Count - 1) then begin

       sSend := 'Paramètres invalides (c2)';
       Socket.SendStr(sSend + CNT_CRLF);
       exit;
    end;

    if iDureeAncien < 1 then
       iDureeAncien := 60;

    seSondageSystemStart.Value := systStart;
    seSondageSystemEnd.Value := systEnd;
    cbSondagePlanete.ItemIndex := iPlaneteUse;
    seSondageDureePourEtrePrisEnCompte.Value := iDureeAncien;

    if iDureeRecent < 1 then
       iDureeRecent := 60;

    seSondageIgnoreDelayLastSondage.Value := iDureeRecent;
    
end;

procedure TfrmRapportHistorique.Services_Commande13_SpiderStatsRefresh(Socket: TBotServicesClient);
var sSend : string;
begin

   chkSpiderStatsGlobales.Checked := true;
   chkSpiderStatsFlottes.Checked := true;
   chkSpiderStatsRecherche.Checked := true;

   if cmdSpiderStatsScan.Enabled = false then begin
      sSend := 'Login non effectué ou autre opération en cours';
      Socket.SendStr(sSend + CNT_CRLF);
      exit;
   end;

   FStatusSocket := Socket;
   cmdSpiderStatsScanClick(nil);
   FStatusSocket := nil;

   
   sSend := 'Terminé';
   Socket.SendStr(sSend + CNT_CRLF);

end;

procedure TfrmRapportHistorique.Services_Commande14_SpiderLogin(Socket: TBotServicesClient);
var r: integer;
    sSend : string;
begin

    FStatusSocket := Socket;
    r := SpiderDoLogin;
    FStatusSocket := nil;


    if r < 0 then begin
       sSend := 'Déjà en cours de login';
    end else if r = 0 then begin
       sSend := 'Echec de login';
    end else begin
       sSend := 'Login réussi';
    end;

    Socket.SendStr(sSend + CNT_CRLF);

end;



procedure TfrmRapportHistorique.Services_Commande10_SpiderVoir(Socket: TBotServicesClient);
var sSend : string;
    fFile: string;
    FS: TFileStream;
    sPlaneteList: string;
    i: integer;
begin


    fFile := FDossierHtml + SERVICES_TPL_SPIDER_VOIR;
    if FileExists(fFile) then begin
      FS := TFileStream.Create(fFile, fmOpenRead);

      SetLength(sSend, FS.Size);
      FS.Read(sSend[1], FS.Size);

      FS.Free;
    end else
      sSend := 'Aucun template de charge';


    sPlaneteList := '';
    for i := 0 to cbGalaxieScanPlanete.Items.Count -  1 do begin
        if cbGalaxieScanPlanete.ItemIndex = i then begin
           sPlaneteList := sPlaneteList + format('<option value="%d" selected>%s</option>', [i, cbGalaxieScanPlanete.Items.Strings[i]]);

        end else
           sPlaneteList := sPlaneteList + format('<option value="%d">%s</option>', [i, cbGalaxieScanPlanete.Items.Strings[i]]);

    end;


    sSend := sfcRemplace(sSend, '<<univers>>',  FCurrentPlayer.Conf.Univers);
    sSend := sfcRemplace(sSend, '<<lgalaxie>>',  FBase2DonneesRapports.Galaxie);

    sSend := sfcRemplace(sSend, '<<rapport_fichier>>', lblProfilFichierRapportDB.Caption);
    sSend := sfcRemplace(sSend, '<<rapport_nbload>>',  lblNbPlanetesLoaded.Caption);
    sSend := sfcRemplace(sSend, '<<galaxie_fichier>>', lblProfilFichierGalaxyDB.Caption);
    sSend := sfcRemplace(sSend, '<<galaxie_nbload>>',  lblNbPlaneteLoadedGalaxy.Caption);

    sSend := sfcRemplace(sSend, '<<planetes_list>>',  sPlaneteList);

    sSend := sfcRemplace(sSend, '<<scan_sstart>>', seGalaxieSystemeStart.Value);
    sSend := sfcRemplace(sSend, '<<scan_send>>',  seGalaxieSystemeEnd.Value);
    sSend := sfcRemplace(sSend, '<<scduree_keep>>',  seSpiderGalaxieDureeRecent.Value);

    sSend := sfcRemplace(sSend, '<<sondage_sstart>>', seSondageSystemStart.Value);
    sSend := sfcRemplace(sSend, '<<sondage_send>>',  seSondageSystemEnd.Value);
    sSend := sfcRemplace(sSend, '<<sdduree_keep>>',  seSondageDureePourEtrePrisEnCompte.Value);
    sSend := sfcRemplace(sSend, '<<sdduree_dontsonde>>',  seSondageIgnoreDelayLastSondage.Value);



    Socket.SendStr(sSend + CNT_CRLF);

end;

procedure TfrmRapportHistorique.Services_Commande07_RecentChangeDuree(Socket: TBotServicesClient; sDuree: string);
var iDuree: integer;
    sSend: string;
begin

    iDuree := StrToIntDef(sDuree, -1);

    if iDuree < 3600 then begin
       sSend := 'Echec';

    end else begin
       seDureeForRecent.Value := iDuree;
       cmdAppliqueAnciennetesClick(nil);

       sSend := 'Ok';
    end;

    Socket.SendStr(sSend + CNT_CRLF);
end;

procedure TfrmRapportHistorique.Services_Commande21_Sondage_VoirList(Socket: TBotServicesClient);
var sSend: string;
begin

    cmdSondageUpdateSGridClick(nil);

    sSend := sgSondages.SaveToHTMLString;
    Socket.SendStr(sSend + CNT_CRLF);

    Socket.SendStr('<br>fin' + CNT_CRLF);
end;

procedure TfrmRapportHistorique.Services_Commande06_Recents_Voir(Socket: TBotServicesClient);
var sSend: string;
begin

    sSend := sgPlanetesRecentes.SaveToHTMLString;
    Socket.SendStr(sSend + CNT_CRLF);

    Socket.SendStr('<br>fin' + CNT_CRLF);
end;


procedure TfrmRapportHistorique.Services_Commande05_DB_Chargement(Socket: TBotServicesClient; IdGalaxie: string);
var iGalaxie: integer;
    sSend : string;
begin

    iGalaxie := StrToIntDef(IdGalaxie, -1);
    if (iGalaxie < 1) or (iGalaxie > 22) then begin
        sSend := 'Hors limite';
        Socket.SendStr(sSend + CNT_CRLF);
        exit;
    end;


    // modifie le SpinEdit
    seDBGalaxie.Value := iGalaxie;

    // Click sur le bouton charger
    cmdLoadDBFromProfilsClick(nil);

    if (FBase2DonneesRapports.Univers > 0) and (FBase2DonneesRapports.Galaxie > 0) then begin
       sSend := 'Ok';
    end else begin
       sSend := 'Echec de chargement';
    end;

    Socket.SendStr(sSend + CNT_CRLF);

end;




procedure TfrmRapportHistorique.cmdGalaxieRecherchePlaneteVideClick(Sender: TObject);
var i: integer;
    sRecherche: string;
    pe: PGalaxiePlanete;
begin

    // txtDBGalaxyJoueur
    if FBase2DonneesPlanete.Count = 0 then exit;



    AfficheMsgGalaxy('');
    AfficheMsgGalaxy('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
    AfficheMsgGalaxy('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
    AfficheMsgGalaxy(_('# Recherche planète vide (en 4, 5 ou 6)'));
    AfficheMsgGalaxy('');


    for i := 0 to FBase2DonneesPlanete.Count - 1 do begin
        pe := FBase2DonneesPlanete.Items[i];

        if (pe.Location.Position > 3) and (pe.Location.Position < 7) then begin
           if pe.Joueur = '' then begin
               AfficheMsgGalaxy(mbtPlanetLocationToStr(pe.Location));
           end;
        end;

    end;

end;

procedure TfrmRapportHistorique.menStatsAllianceClick(Sender: TObject);
var peGalaxie: PGalaxiePlanete;
begin

    if FSondageAlliance <> '' then begin
          txtAlliance.Text := FSondageAlliance; // peGalaxie.Alliance;

          cmdScanAllianceClick(nil);

          // Affiche l'onglet
          pcSwitch.ActivePageIndex := tabOutils.PageIndex;
          pcOutils.ActivePageIndex := tabOutilsStatistiques.PageIndex;

    end;

(*
    if FCurrentRapport = nil then exit;

    peGalaxie := FBase2DonneesPlanete.Get_Pointeur(FCurrentRapport.PlaneteLocation);

    if peGalaxie <> nil then begin
       if peGalaxie.Alliance <> '' then begin
          txtAlliance.Text := FSondageAlliance; // peGalaxie.Alliance;

          cmdScanAllianceClick(nil);

          // Affiche l'onglet
          pcSwitch.ActivePageIndex := tabStatsAlliance.PageIndex;
       end;
    end;
*)

end;

procedure TfrmRapportHistorique.menRecentsTrieGTClick(Sender: TObject);
begin
    FBaseRecent.TrieParGT;
    UpdateAllSpec(sgPlanetesRecentes, FBaseRecent);
end;

procedure TfrmRapportHistorique.menRecentsTrieFlotteClick(Sender: TObject);
begin
    FBaseRecent.TrieFlottes;
    UpdateAllSpec(sgPlanetesRecentes, FBaseRecent);
end;

procedure TfrmRapportHistorique.menRecentsTrieLastAttaqueClick(Sender: TObject);
begin
    FBaseRecent.TrieDureeAttaque;
    UpdateAllSpec(sgPlanetesRecentes, FBaseRecent);
end;

procedure TfrmRapportHistorique.menRecentSuppriFlagTropPeuDevClick(
  Sender: TObject);
begin

    FBaseRecent.DeleteFlag(FLAG_MODE_TROP_PEUDEV);
    FBase2DonneesRapports.SaveToFile('');
    UpdateAllSpec(sgPlanetesRecentes, FBaseRecent);
end;

procedure TfrmRapportHistorique.menFiltreTrierParDateAttaqueClick(
  Sender: TObject);
begin
    FBaseFiltree.TrieDureeAttaque;
    UpdateAllSpec(sgFiltrer, FBaseFiltree);
end;

procedure TfrmRapportHistorique.menFiltreTrierParFlotteClick(Sender: TObject);
begin
    FBaseFiltree.TrieFlottes;
    UpdateAllSpec(sgFiltrer, FBaseFiltree);
end;

procedure TfrmRapportHistorique.menMettreAJourLempireClick(Sender: TObject);
var r: integer;
begin
    EnableOrDisableWebActionButton(false);

    // Met tout à jour
    r := FCurrentPlayer.ProceedUpdateEverythingOnEveryPlanet(true);

    if r > 0 then begin
       // Sauvegarde
       FCurrentPlayer.SaveToFile('');


       // Raffraichi les données
       RefreshPlanetGrid(FCurrentPlayer);

       // Raffraichi les données
       RefreshPlanetGridAutoConstruction(FCurrentPlayer);

    end else begin
       Status('MettreAJourLempire - Erreur: ' + IntToStr(r));

    end;
    
    EnableOrDisableWebActionButton(true);

end;

procedure TfrmRapportHistorique.menObservationCdRStartClick(Sender: TObject);
begin
   OpenCdRMonitor;
end;

procedure TfrmRapportHistorique.sgVaisseauxEditingDone(Sender: TObject);
begin
    ReadVaisseauxQuantite;
    UpdateSpeedAndDeutUsed;
end;



procedure TfrmRapportHistorique.timServiceDelayCmdTimer(Sender: TObject);
var iSave: integer;
begin

   iSave := FServiceDelayCmd;
   if FServiceDelayCmd = 0 then exit;
   FServiceDelayCmd := 0;

   
   case iSave of
      // Commande: GET spider_sondeinactif
      SERVICES_CMD_SPIDER_SONDEINACTIFS: begin
                                            if cmdSondageStart.Enabled then
                                               cmdSondageStartClick(nil);
                                         end;

      // Commande: GET spider_statsrehresh
      SERVICES_CMD_SPIDER_SCAN: begin
                                   if cmdSpiderGalaxieScan.Enabled then
                                      cmdSpiderGalaxieScanClick(nil);
                                end;

      SERVICES_CMD_SPIDER_READMSG: begin
                                    if cmdMessageListGet.Enabled then
                                       cmdMessageListGetClick(nil);

                                end;
      SERVICES_CMD_DO_GET_FORUM_AUTORIZATION: begin
                                DoForumGetAccess;
                           end;
   end;


end;

procedure TfrmRapportHistorique.Sauvegarder1Click(Sender: TObject);
begin
   FCurrentPlayer.Conf.SaveToFile('');
   FBase2DonneesRapports.SaveToFile('');
   FBase2DonneesPlanete.SaveToFile('');

   FLocalSetting.SaveToFile('', [lsoEnteteValues, lsoIniData]);


   if FCurrentPlayer.allPlanetes.Count > 0 then begin
      FCurrentPlayer.SaveToFile('');
   end;

end;

procedure TfrmRapportHistorique.Recycleurs1Click(Sender: TObject);
begin
    FBaseRecent.TrieRecycleur;
    UpdateAllSpec(sgPlanetesRecentes, FBaseRecent);
end;

procedure TfrmRapportHistorique.rierparrecycleurs1Click(Sender: TObject);
begin
    FBaseFiltree.TrieRecycleur;
    UpdateAllSpec(sgFiltrer, FBaseFiltree);
end;

procedure TfrmRapportHistorique.Arrteroperationencours1Click(Sender: TObject);
begin
   FCurrentPlayer.sockHTTP.Abort;
end;

procedure TfrmRapportHistorique.cbAttaquePlaneteChange(Sender: TObject);
begin
    // le profil est modifié uniquement si on effectue une attaque
    cbListAttaquePlaneteDepart.ItemIndex := cbAttaquePlanete.ItemIndex;
end;

procedure TfrmRapportHistorique.cbAttaqueSpeedRatioChange(Sender: TObject);
begin
   UpdateSpeedAndDeutUsed;
end;

procedure TfrmRapportHistorique.cmdFlotteAttaqueRefreshDateClick(
  Sender: TObject);
begin
    sggUpdateFlotteList(sgGridFlotteList, FCurrentPlayer.cFlotteVaisseaux.FlotteList, FCurrentPlayer);
end;

procedure TfrmRapportHistorique.cmdSpiderEffacerMsgDebugClick(Sender: TObject);
begin
    txtDebug1.Lines.Clear;
end;

procedure TfrmRapportHistorique.chkDesactiveColonneDefClick(Sender: TObject);
begin
    //InitGrille(sgPlanetes);
    InitGrille(sgPlanetesRecentes);
    InitGrille(sgPlanetesPoulesDor);
    InitGrille(sgFiltrer);

end;

procedure TfrmRapportHistorique.chkFastEvacuationToDebrisClick(Sender: TObject);
begin
    // décoche les autres
    chkFastEvacuationToMoon.Checked := false;
    chkFastEvacuationToPlanete.Checked := false;

    chkFastEvacuationToDebris.Checked := true;
end;

procedure TfrmRapportHistorique.chkFastEvacuationToMoonClick(Sender: TObject);
begin
    chkFastEvacuationToDebris.Checked := false;
    chkFastEvacuationToPlanete.Checked := false;

    chkFastEvacuationToMoon.Checked   := true;
end;

procedure TfrmRapportHistorique.chkFastEvacuationToPlaneteClick(
  Sender: TObject);
begin
   chkFastEvacuationToDebris.Checked := false;
   chkFastEvacuationToMoon.Checked   := false;

   chkFastEvacuationToPlanete.Checked := true;
end;

procedure TfrmRapportHistorique.cmdAttackWithPTClick(Sender: TObject);
begin

    FCurrVaisseuxList := FCurrentPlayer.cFlotteVaisseaux.VaisseauxList;

    // Remet à 0 le nombre de GT
    FCurrVaisseuxList.SetVaisseauxAUtiliser(203, 0);

    // Définit le nombre de PT
    FCurrVaisseuxList.SetVaisseauxAUtiliser(202, FNbPTForCurrentRapport);

    UpdateVaisseaux(sgVaisseaux);

end;

procedure TfrmRapportHistorique.menRecentAttaqueAutoClick(Sender: TObject);
begin
    // Attaque automatiquement les plus faible
    
end;

procedure TfrmRapportHistorique.sgSondagesClickCell(Sender: TObject; ARow, ACol: Integer);
var i: integer;
   // pe: PPlaneteASonder;
    Tmp: PRapportHead;
    peGalaxie: PGalaxiePlanete;
begin

    // gbPlanete
    i := ARow - 1;

    if (i < 0) or (i >= FCurrentPlayer.SondagePlanetesList.Count) then exit;

    FCurrentSondageSel := FCurrentPlayer.SondagePlanetesList.Items[i];

    Tmp := FBase2DonneesRapports.Get_Pointeur(FCurrentSondageSel.Coord);

    if Tmp <> nil then begin
       FCurrentRapport := Tmp;
       FRowCurrentRapport := ARow;
       LoadCurrentInForm;

    end else begin
       ModifStatsMenu(FCurrentSondageSel.Coord);
    end;

end;

procedure TfrmRapportHistorique.cmdScanAlliance2Click(Sender: TObject);
begin
   FStatsAlliance.ScanAlliance(txtAlliance2.Text);
   UpdateStatsAlliance(gdStats2);
end;

procedure TfrmRapportHistorique.txtAllianceEnter(Sender: TObject);
begin
   cmdScanAlliance2.Default := false;
   cmdScanAlliance.Default := true;
end;

procedure TfrmRapportHistorique.txtAlliance2Enter(Sender: TObject);
begin
   cmdScanAlliance.Default := false;
   cmdScanAlliance2.Default := true;
end;

procedure TfrmRapportHistorique.menRecentsDefensesClick(Sender: TObject);
begin
    FBaseRecent.TrieSDefenses;
    UpdateAllSpec(sgPlanetesRecentes, FBaseRecent);
end;


procedure TfrmRapportHistorique.cmdSondageJoueurOrAlliance(Str: string; bIsPlayer: boolean);
var peGalaxie: PGalaxiePlanete;
    Coord: TPlanetLocation;
    iPosition: integer;
    iSystem: integer;
    Duree: int64;

    NbAjoute: integer;

begin


   if seSondageSystemEnd.Value < seSondageSystemStart.Value then begin
      iSystem := seSondageSystemEnd.Value;
      seSondageSystemEnd.Value := seSondageSystemStart.Value;
      seSondageSystemStart.Value := iSystem;
   end;



   FCurrDate := DateTimeToUnix(Now);
   NbAjoute := 0;

   Coord.Galaxie := FBase2DonneesPlanete.Galaxie;

   for iSystem := seSondageSystemStart.Value to seSondageSystemEnd.Value do begin

       Coord.SystemSolaire := iSystem;

       for iPosition := 1 to 15 do begin
           Coord.Position := iPosition;

           peGalaxie := FBase2DonneesPlanete.Get_Pointeur(Coord);

           if peGalaxie <> nil then begin
              Duree := FCurrDate - peGalaxie.Date;

              if Duree <= seSondageDureePourEtrePrisEnCompte.Value then begin

                  if NoT(bIsPlayer) and SondageGetPointsVerification(peGalaxie.Joueur) then begin
                     // On ajoute les joueurs d'une alliance
                     // On prend donc en compte la vérification des points
                     if SameText(Str, peGalaxie.Alliance)  then begin

                        if SondageCheckAndTryToAddThisCoord(Coord, peGalaxie, true) then
                           Inc(NbAjoute);

                     end;

                  end else if bIsPlayer then begin
                     // On ajoute un joueur précis, on ignore la vérification des points
                      if SameText(Str, peGalaxie.Joueur)  then begin
                         if SondageCheckAndTryToAddThisCoord(Coord, peGalaxie, true) then
                            Inc(NbAjoute);

                      end;

                  end;


              end else begin
                 Status(_('Sondage - Non pris en compte car trop ancien: ') + mbtPlanetLocationToStr(peGalaxie.Location));

              end;

           end else begin
              Status(_('Sondage - Non scanné: ') + mbtPlanetLocationToStr(Coord));

           end;

       end;

   end;

   Status(_('Sondage - Total ajouté: ') + IntToStr(NbAjoute));

end;

procedure TfrmRapportHistorique.cmdSondageJoueurClick(Sender: TObject);
var sCmp: string;
begin
   SondageLockCmd(false);

   sCmp := trim(txtSondageAllianceOrJoueur.Text);

   cmdSondageJoueurOrAlliance(sCmp, true);

   SondageLockCmd(true);
end;

procedure TfrmRapportHistorique.cmdSondageAllianceClick(Sender: TObject);
var sCmp: string;
begin
   SondageLockCmd(false);

   sCmp := trim(txtSondageAllianceOrJoueur.Text);

   cmdSondageJoueurOrAlliance(sCmp, false);

   SondageLockCmd(true);
end;

procedure TfrmRapportHistorique.menEspionnerSesPlantesClick(Sender: TObject);
var peGalaxie: PGalaxiePlanete;
begin

    if FCurrentRapport = nil then begin
       Status(_('Liste des rapports - Erreur'));

    end else begin

       peGalaxie := FBase2DonneesPlanete.Get_Pointeur(FCurrentRapport.PlaneteLocation);

       if peGalaxie <> nil then begin
          txtSondageAllianceOrJoueur.Text := peGalaxie.Joueur;
          pcUniversRapports.ActivePageIndex := tabEspionnage.PageIndex;
          pcEspionnage.ActivePageIndex := tabEspionnageIn.PageIndex;
       end;

    end;

end;

//  0                                        aucune fois                                             première
// -1 signifie que la cible a déjà été attaqué une fois et donc que l'échec s'est produite lors de la seconde attaque
// -2                                          deux                                                   troisième
function ExtractNbEnvoi(Valeur: int64): integer;
begin
   if Valeur > 0 then begin
      // déjà tout envoyé
      Result := -1;
      exit;
   end;

   if Valeur = 0 then begin
      // aucun envoi
      Result := 0;
      exit;
   end;

   Result := -1 * Valeur;

   // supprime les centaines
   Result := Result and $0000000F;
end;

// chaque centaine correspond à une erreur
//  1000 = 1 erreur
//  3000 = 3 erreur
// 12000 = 12 erreur
function ExtractNbEchec(Valeur: int64): integer;
begin
   if Valeur > 0 then begin
      // déjà tout envoyé
      Result := 0;
      exit;
   end;

   if Valeur > -10 then begin
      // aucun échec
      Result := 0;
      exit;
   end;

   Result := Valeur;

   // supprime les dizaines
   Result := Result and $0000FF00;
   Result := Result shr 8;
end;

function IncEchec(Valeur: int64): int64;
var NbEchec: integer;
    lVal: integer;
begin

    NbEchec := ExtractNbEchec(Valeur);
    Inc(NbEchec);
    NbEchec := NbEchec shl 8;

    lVal := Valeur;
    lVal := lVal and $FFFF00FF;
    lVal := lVal or NbEchec;

    Result := lVal;
end;




procedure TfrmRapportHistorique.cmdStatsChercheFromUIDClick(Sender: TObject);
var uid: integer;
    p: PPlayerStats;
begin

     if FCurrentPlayer = nil then begin
        exit;
     end;
     
     uid := StrToIntDef(trim(txtStatsUID.Text), -1);
     p   := FCurrentPlayer.StatsPlayer.Get_UID(uid);

     if p <> nil then begin
        txtDBPlanetes.Lines.Add(p.Nom);
        txtDBPlanetes.Lines.Add(p.Alliance);
     end;

end;

procedure TfrmRapportHistorique.cmdSondageResetDateClick(Sender: TObject);
begin
    FCurrentPlayer.SondagePlanetesList.ResetDateToZero;

    cmdSondeAttaqueEffacerDejaSonde.Enabled := true;
end;

procedure TfrmRapportHistorique.menSondageEnleverAllianceClick(Sender: TObject);
var i: integer;
    pe: PPlaneteASonder;
    peGalaxie, peGalTest: PGalaxiePlanete;
begin
    // enlève l'élément
    if FCurrentSondageSel <> nil then begin
       i := FCurrentPlayer.SondagePlanetesList.IndexOf(FCurrentSondageSel);

       if i >= 0 then begin

          pe := FCurrentPlayer.SondagePlanetesList.Items[i];

          peGalaxie := FBase2DonneesPlanete.Get_Pointeur(pe.Coord);

          FCurrentPlayer.SondagePlanetesList.Delete(i);
          pe := nil;

          if (peGalaxie <> nil) and (FCurrentPlayer.SondagePlanetesList.Count > 0) then begin

             for i := FCurrentPlayer.SondagePlanetesList.Count - 1 downto 0 do begin
                pe := FCurrentPlayer.SondagePlanetesList.Items[i];

                peGalTest := FBase2DonneesPlanete.Get_Pointeur(pe.Coord);

                if peGalTest <> nil then begin
                   if SameText(peGalTest.Alliance, peGalaxie.Alliance) then begin
                      // supprime
                      FCurrentPlayer.SondagePlanetesList.Delete(i);
                   end;
                end;
             end;
          end;


          UpdateSondages(sgSondages);
       end;

    end;

end;

procedure TfrmRapportHistorique.menSondageEnleverClick(Sender: TObject);
var i: integer;
begin
    // enlève l'élément
    if FCurrentSondageSel <> nil then begin
       i := FCurrentPlayer.SondagePlanetesList.IndexOf(FCurrentSondageSel);

       if i >= 0 then begin
          FCurrentPlayer.SondagePlanetesList.Delete(i);
          UpdateSondages(sgSondages);
       end;

    end;

end;

(*
procedure TfrmRapportHistorique.Button5Click(Sender: TObject);
var d: int64;
    r: integer;
begin


    r := GetNbSondeToSend(150000, 8000, 1, 0);
    AfficheMsgGalaxy(IntToStr(r));

    r := GetNbSondeToSend(150000, 8000, 2, 0);
    AfficheMsgGalaxy(IntToStr(r));

    r := GetNbSondeToSend(150000, 8000, 3, 0);
    AfficheMsgGalaxy(IntToStr(r));


    exit;

    d := -1;

    r := ExtractNbEnvoi(d);
    AfficheMsgGalaxy(IntToStr(r));

    r := ExtractNbEchec(d);
    AfficheMsgGalaxy(IntToStr(r));

    d := IncEchec(d);
    r := ExtractNbEnvoi(d);
    AfficheMsgGalaxy(IntToStr(r));
    r := ExtractNbEchec(d);
    AfficheMsgGalaxy(IntToStr(r));

    Dec(d);
    r := ExtractNbEnvoi(d);
    AfficheMsgGalaxy(IntToStr(r));

    Dec(d);
    r := ExtractNbEnvoi(d);
    AfficheMsgGalaxy(IntToStr(r));

    d := IncEchec(d);
    r := ExtractNbEnvoi(d);
    AfficheMsgGalaxy(IntToStr(r));
    r := ExtractNbEchec(d);
    AfficheMsgGalaxy(IntToStr(r));

    d := IncEchec(d);
    r := ExtractNbEnvoi(d);
    AfficheMsgGalaxy(IntToStr(r));
    r := ExtractNbEchec(d);
    AfficheMsgGalaxy(IntToStr(r));

    Dec(d);
    r := ExtractNbEnvoi(d);
    AfficheMsgGalaxy(IntToStr(r));

end;
*)

procedure TfrmRapportHistorique.cmdExportSQLClick(Sender: TObject);
const OGSpy_Insert  = 'INSERT  INTO `%s` VALUES (''%d'', %d, ''%d'', ''%d'', ''%s'', ''%s'', ''%s'', ''%s'', %d, %s);';
      OGSpy_Replace = 'REPLACE INTO `%s` VALUES (''%d'', %d, ''%d'', ''%d'', ''%s'', ''%s'', ''%s'', ''%s'', %d, %s);';
//                                                Galaxy Syst Pos     Lune  Planete Alliance Joueur   status date userid
//                                0                 1      2   3       4       5       6       7         8     9   10

      OGSpy_Update  = 'UPDATE `%s` SET `moon` = ''%4:d'', `name` = ''%5:s'', `ally` = ''%6:s'', `player` = ''%7:s'', `status` = ''%8:s'', `last_update` = ''%9:d'', `last_update_user_id` = ''%10:s''  WHERE `galaxy` = ''%1:d'' AND `system` = %2:d AND `row` = ''%3:d'' LIMIT 1;';




      GalaxyTool_Insert  = 'INSERT  INTO `%s` VALUES (''%d'', %d, ''%d'', ''%d'', ''%s'', ''%d'', ''%d'', ''%d'', ''%s'', ''%s'', ''%s'', ''%s'', ''%d'', ''%s'', DEFAULT, DEFAULT);';
      GalaxyTool_Replace = 'REPLACE INTO `%s` VALUES (''%d'', %d, ''%d'', ''%d'', ''%s'', ''%d'', ''%d'', ''%d'', ''%s'', ''%s'', ''%s'', ''%s'', ''%d'', ''%s'', DEFAULT, DEFAULT);';
      //                                            Galaxy System Position Lune   Coord  MoonSize Metal  Cristal Alliance Planet Joueur  status   date   userid
//                                0                    1      2     3        4       5       6       7       8       9      10     11      12      13      14


      GalaxyTool_Update  = 'UPDATE `%s` SET `mond` = ''%4:d'',  `mondgr` = ''%6:d'', `metall` = ''%7:d'', `kristall` = ''%8:d'', `ally` = ''%9:s'', `planetname` = ''%10:s'', ' +
                           '`spielername` = ''%11:s'', `status` = ''%12:s'', `zeit` = ''%13:d'', `userid` = ''%14:s''  WHERE `galaxie` = ''%1:d'' AND `system` = %2:d AND `planet` = ''%3:d'' LIMIT 1;';


      OGSpy302_Replace = 'REPLACE INTO `%s` VALUES (''%d'', %d, ''%d'', ''%d'',  0, 0, ''%s'', ''%s'', ''%s'', ''%s'', %d, 0, %s);';
//                                                   Galaxy Syst  Pos   Lune   phalanx Planete Alliance Joueur   status date userid
//                                   0                 1      2   3       4     gate      5       6       7         8     9   10


var i, MoonSize: integer;
    pe: PGalaxiePlanete;
    sAdd, sStatus, sFormat, sPlanete, sFile: string;
    HasLune: integer;

    F: TextFile;
    sFileCharAdd: string;
    iMisc: int64;
    OGSpyLike: boolean;
begin

(*

INSERT INTO `galaxie` ( `galaxie` , `system` , `planet` , `mond` , `coordinates` , `mondgr` , `metall` , `kristall` , `ally` , `planetname` , `spielername` , `status` , `zeit` , `userid` , `notices` , `reports` )
VALUES (
'2', '1', '4', '1', '2:1:4', '300', '0', '0', 'ALLY', 'planete name', 'Joueur Name', '', '1149699724', '1', 'false', 'false'
);



UPDATE `ogspy_universe` SET `moon` = '1',
`name` = 'planete name',
`ally` = 'x',
`player` = 'Joueur',
`last_update` = '1137534214' WHERE `galaxy` = '3' AND `system` =2 AND `row` = '2' LIMIT 1 ;
*)

// INSERT INTO `ogspy_universe` VALUES ('3', 2, '1', '0', 'planete name', '', 'Joueur', '', 1137577417, 1);
// INSERT INTO `ogspy_universe` VALUES ('3', 2, '2', '0', 'planete name', '', 'Joueur', '', 1137536617, 1);
(*
CREATE TABLE `ogspy_universe` (
  `galaxy` enum('1','2','3','4','5','6','7','8','9') NOT NULL default '1',
  `system` smallint(3) NOT NULL default '0',
  `row` enum('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15') NOT NULL default '1',
  `moon` enum('0','1') NOT NULL default '0',
  `name` varchar(20) NOT NULL default '',
  `ally` varchar(20) default NULL,
  `player` varchar(20) default NULL,
  `status` enum('','i','I','d','di','dI') NOT NULL default '',
  `last_update` int(11) NOT NULL default '0',
  `last_update_user_id` int(11) NOT NULL default '0',
  UNIQUE KEY `univers` (`galaxy`,`system`,`row`),
  KEY `player` (`player`)
) TYPE=MyISAM;
*)


    FExportSQLStop := false;

    AfficheMsgGalaxy('');
    AfficheMsgGalaxy('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
    AfficheMsgGalaxy('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');

    if optExportOGSpy.Checked then
       AfficheMsgGalaxy(_('# Exportation SQL OSpy: '))
    else if optExportOGSpy302.Checked then
       AfficheMsgGalaxy(_('# Exportation SQL OSpy 3.02: '))
    else
       AfficheMsgGalaxy(_('# Exportation SQL Galaxy Tool: '));


    AfficheMsgGalaxy('');

    if chkExportFichier.Checked then begin
       sFile := IncludeTrailingPathDelimiter(ExtractFileDir(Application.ExeName));

       if optExportSQLInsert.Checked then
          sFileCharAdd := 'i'
       else if optExportSQLReplace.Checked then
          sFileCharAdd := 'r'
       else
          // update sinon
          sFileCharAdd := 'u';

       if optExportOGSpy.Checked or optExportOGSpy302.Checked then
          sFileCharAdd := sFileCharAdd + 'OGS'
       else
          sFileCharAdd := sFileCharAdd + 'GT';


       sFile := sFile + format('u%d_g%d%s.sql', [FBase2DonneesPlanete.Univers, FBase2DonneesPlanete.Galaxie, sFileCharAdd]);
       AssignFile(F, sFile);


       AfficheMsgGalaxy(_('Fichier :') + sFile);

       
       {$I-}
       ReWrite(F);
       {$I+}
    end;


    if FBase2DonneesPlanete.Count = 0 then begin
       AfficheMsgGalaxy(_('Echec'));
       exit;
    end;

    FCurrDate := -1;

    if chkExportUseUniformDate.Checked then begin
       for i := 0 to FBase2DonneesPlanete.Count - 1 do begin
           pe := FBase2DonneesPlanete.Items[i];

           if FCurrDate < 0 then
              FCurrDate := pe.Date;

           if FCurrDate > pe.Date then
              FCurrDate := pe.Date;
       end;

       if FCurrDate < 0 then begin
          AfficheMsgGalaxy(_('Echec - Date indéfinissable'));
          exit;
       end;
    end;


    OGSpyLike := false;
    if optExportOGSpy.Checked then begin
       if optExportSQLInsert.Checked then
          sFormat := OGSpy_Insert
       else if optExportSQLReplace.Checked then
          sFormat := OGSpy_Replace
       else
          sFormat := OGSpy_Update;

       OGSpyLike := true;

    end else if optExportOGSpy302.Checked then begin
       sFormat := OGSpy302_Replace;
       OGSpyLike := true;


    end else begin

       if optExportSQLInsert.Checked then
          sFormat := GalaxyTool_Insert
       else if optExportSQLReplace.Checked then
          sFormat := GalaxyTool_Replace
       else
          sFormat := GalaxyTool_Update;

    end;

    AfficheMsgGalaxy('');
    AfficheMsgGalaxy('# Using format: ' + sFormat);
    AfficheMsgGalaxy('');



    for i := 0 to FBase2DonneesPlanete.Count - 1 do begin
        pe := FBase2DonneesPlanete.Items[i];

        if pe.Lune.Surface > 0 then begin
           HasLune := 1;
           MoonSize := pe.Lune.Surface;
        end else begin
           HasLune := 0;
           MoonSize := 0;
        end;



        sStatus := '';

        if OGSpyLike then begin
           // OGSpy:
           // enum('', 'i', 'I', 'd', 'di', 'dI')
           if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_USER_BLOQUE, pe.Flags) then begin
              sStatus := 'd';
           end;
           if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_INACTIF_4SEMAINES, pe.Flags) then begin
              sStatus := sStatus + 'I';
           end else if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_INACTIF_2SEMAINES, pe.Flags) then begin
              sStatus := sStatus + 'i';
           end;

        end else begin
           // Galaxy tool
           // Les lettres sont les même dans la base de données et
           // sont adaptés lors de l'affichage
           // Voir fichier show.php (vers la fin)
           if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_USER_BLOQUE, pe.Flags) then begin
              sStatus := 'g';
           end;
           if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_INACTIF_4SEMAINES, pe.Flags) then begin
              sStatus := sStatus + 'I';
           end else if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_INACTIF_2SEMAINES, pe.Flags) then begin
              sStatus := sStatus + 'i';
           end;
           if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_PROTECTION_NOOB_TROPFAIBLE, pe.Flags) or sfcFlagsIsIn(CNT_GALAXIE_FLAGS_PROTECTION_NOOB_TROPFORT, pe.Flags) then begin
              sStatus := sStatus + 'n';
           end;
           if sfcFlagsIsIn(CNT_GALAXIE_FLAGS_MODE_VACANCES, pe.Flags) then begin
              sStatus := sStatus + 'u';
           end;

        end;


        
        if chkExportUseUniformDate.Checked = false then begin
           // Utilise la date de la planete...
           FCurrDate := pe.Date;

           // Cependant, on va l'arrondir
           iMisc     := FCurrDate mod 5000;
           FCurrDate := FCurrDate - iMisc;
        end;

        
        sPlanete := sfcRemplace(pe.NomPlanete, '''', '\''');


        // LongStringToUTF8String

        if OGSpyLike then begin
           // OGSpy
           //if chkUTF8.Checked then begin
(*
			$texte .= utf8_decode($name)."<||>";
			$texte .= utf8_decode($player)."<||>";
			$texte .= utf8_decode($ally)."<||>";
			$texte .= utf8_decode($user_name);
*)
              //sAdd := format(sFormat, [txtOSpyDB.Text, pe.Location.Galaxie, pe.Location.SystemSolaire, pe.Location.Position, HasLune, LongStringToUTF8String(sPlanete), LongStringToUTF8String(pe.Alliance), LongStringToUTF8String(pe.Joueur), sStatus, FCurrDate, LongStringToUTF8String(txtOSpyUserID.Text)]);

           //end else begin
              sAdd := format(sFormat, [txtOSpyDB.Text, pe.Location.Galaxie, pe.Location.SystemSolaire, pe.Location.Position, HasLune, sPlanete, pe.Alliance, pe.Joueur, sStatus, FCurrDate, txtOSpyUserID.Text]);

           //end;

        end else begin
           // Galaxy Tool

           sAdd := format(sFormat, [txtOSpyDB.Text, pe.Location.Galaxie, pe.Location.SystemSolaire, pe.Location.Position, HasLune, mbtPlanetLocationToStr(pe.Location), MoonSize, 0, 0,  pe.Alliance, sPlanete, pe.Joueur, sStatus, FCurrDate, txtOSpyUserID.Text]);

           // , MoonSize

        end;



        // Galaxy System Position Lune  Planete Alliance Joueur status date userid
        if chkExportFichier.Checked then begin
           WriteLn(F, sAdd);
        end else begin
           AfficheMsgGalaxy(sAdd);
        end;

        if (i mod 50 = 0) then begin
           Application.ProcessMessages;

           if FExportSQLStop then
              break;
        end;

    end;


    if chkExportFichier.Checked then begin
       WriteLn(F, '');
       
       CloseFile(F);

       AfficheMsgGalaxy(_('Terminé'));
    end;

end;

procedure TfrmRapportHistorique.cmdExportStopClick(Sender: TObject);
begin
    FExportSQLStop := true;
end;

procedure TfrmRapportHistorique.cmdClearPlanetMsgClick(Sender: TObject);
begin
    txtDBPlanetes.Lines.Clear;
end;

procedure TfrmRapportHistorique.cmdClipboardParseRapportClick(Sender: TObject);
var Msg, sRapport: string;
    xPos, r: integer;
begin

    Msg := Clipboard.AsText;

    if pos(#$0D, Msg) = 0 then begin
       // Il y a qu'une seule ligne
       exit;
    end;

    Clipboard.AsText := '';

    repeat
       xPos := pos('Matières premières', Msg);
       if xPos = 0 then break;
       
       System.Delete(Msg, 1, xPos - 1);

       xPos := pos('flotte d''espionnage', Msg);
       sRapport := copy(Msg, 1, xPos - 1);
       System.Delete(Msg, 1, xPos - 1);

       xPos := pos('%', Msg);
       sRapport := sRapport + copy(Msg, 1, xPos);
       System.Delete(Msg, 1, xPos);

       txtRapport.Text := sRapport;

       // analyse
       r := AnalyseRapportCurr;

       if (r > 0) and (FRapportLastAdd <> nil) then begin
         {$IFDEF DEBUG}
              Status('Presse-Papier - Rapport ajouté: ' + mbtPlanetLocationToStr(FRapportLastAdd.PlaneteLocation));
         {$ENDIF}
       end;

    until False;

    
end;

procedure TfrmRapportHistorique.cmdSpiderVueGeneraleClick(Sender: TObject);
var r: integer;
    p: TParsingApercu;
    i: integer;
    pe: PAppMessage;
begin
    r := FCurrentPlayer.ProceedUpdateApercu;

    p := FCurrentPlayer.cParsing.pApercu;

    Status(_('Informations de l''aperçu:'));
    Status(format(_('Cases occupées: %d sur %d'), [p.CasesOccupees, p.CasesTotales]));
    Status(format(_('Points: %s'), [sfcFormatStrToMilliersPX(p.Points)]));
    Status(format(_('Classement: %s'), [sfcFormatStrToMilliersPX(p.ClassementPosition)]));
    Status(format(_('Participant: %s'), [sfcFormatStrToMilliersPX(p.ClassementNbJoueurs)]));
    Status(format(_('Planète: '), [p.NomPlanete]));
    Status(format(_('Joueur: '), [p.NomJoueur]));
    Status('Planète location: ' + FCurrentPlayer.cParsing.pHeader.PlaneteStr);




    if p.MsgList.Count > 0 then begin

       for i := 0 to p.MsgList.Count - 1 do begin
           pe := p.MsgList.Items[i];

           if NoT(pe.bColorMenace) then begin
              Status('Couleur: Verte - ' + ESBDGetDureeStrings(pe.Duree, true) + ' - ' + DateTimeToStr(ESBDates.UnixToDateTime(pe.DateImpact + FCurrentPlayer.DifferenceHeureLocaleHeureServeur)) + ' - Msg:' + pe.Msg);
              //Continue;
           end;

           Status('-----------');
           Status('Ordre: ' + mamOrdreToStr(pe.Ordre));
           Status('Direction: ' + mamDirectionToStr(pe.Direction));
           Status('Durée: ' + ESBDGetDureeStrings(pe.Duree, true) + ' [' + IntToStr(pe.DateImpact) + ']');

           Status('Impact Local: ' + DateTimeToStr(ESBDates.UnixToDateTime(pe.DateImpact + FCurrentPlayer.DifferenceHeureLocaleHeureServeur)) + ' (Serveur: ' + DateTimeToStr(ESBDates.UnixToDateTime(pe.DateImpact)) + ')');



           if pe.bColorMenace then
             Status('Couleur: Rouge')
           else begin
             Status('Couleur: Verte (ignoré)');
           end;

           if pe.bOwnFlotte then
             Status('Flotte: Propre flotte' + pe.PlayerFlotte)
           else
             Status('Flotte: Flotte d''un autre joueur: ' + pe.PlayerFlotte);

           Status('Départ: ' + pe.DepartStr + ' [' + mbtPlanetLocationToStr(pe.Depart) + ']');
           Status('Arrivée: ' + pe.ArriveeStr + ' [' + mbtPlanetLocationToStr(pe.Arrivee) + ']');



           Status('Nombre de vaisseaux: ' + sfcFormatStrToMilliersPX(pe.NbVaisseau));
           Status('Vaisseaux: ' + pe.VaisseauxStr);

           Status('Message complet: ' + pe.Msg);

       end;


    end else begin
       Status('Aucun mouvement de flotte');
    end;

    AfficheTOGRessourceAll(FCurrentPlayer.cParsing.pHeader.CurrRessource);


end;

procedure TfrmRapportHistorique.cmdHelpRapportPlaneteClick(Sender: TObject);
begin

   cmdHelpRapportPlanete.Enabled := false;


   // Hint Line 1
   seSondageDureePourEtrePrisEnCompte.Hint := _('Permet de ne sonder UNIQUEMENT les éléments (planètes et lunes) qui ont été cartographié avant cette durée.') +
   #$0D#$0A +

   // Hint line 2
   _('Cela évite de sonder des éléments qui ne sont pas à jour en évitant ainsi de prendre le risque de tomber sur des planètes détruites, joueurs en vacances ou avec protection des noob.') +
   #$0D#$0A +

   // Hint line 3
   _('Un click droit permet d''afficher un menu proposant de choisir facilement une durée.');

   seSondageDureePourEtrePrisEnCompte.ShowHint := true;



   seSondageIgnoreDelayLastSondage.Hint := _('Permet d''éviter d''ajouter des éléments à sonder qui ont DEJA été sondé avant cette durée');
   seSondageIgnoreDelayLastSondage.ShowHint := true;



   chkSondageDoDateVerifForRapportToo.Hint := _('Permet de ne sonder uniquement les éléments qui ont DEJA été SONDER avant la durée spécifiée.') + #$0D#$0A +
   _('Cette option est généralement inutile, elle servait lorsque les attaques aux sondes étaient possible');

   chkSondageDoDateVerifForRapportToo.ShowHint := true;
   

   ShowHintHelp(seSondageIgnoreDelayLastSondage);

   ShowHintHelp(seSondageDureePourEtrePrisEnCompte, 20000);

   ShowHintHelp(chkSondageDoDateVerifForRapportToo, 20000);

   cmdHelpRapportPlanete.Enabled := true;

end;

procedure TfrmRapportHistorique.cmdHelpSpiderAllClick(Sender: TObject);
begin
   cmdHelpSpiderAll.Enabled := false;

   cmdHelpSpiderScanClick(Sender);


   cmdHelpSpiderAll.Enabled := true;
end;

procedure TfrmRapportHistorique.ShowHintHelp(Where: TControl; Duration: integer = -1; DoSleepPause: boolean = true);
var NbMots: integer;
    max: longword;
begin


    if Where.Hint <> '' then begin
       if Duration < 0 then begin
          // calcul automatiquement la durée en fonction de la longueur

          // Numéro de la galaxie qui va être scanné
          // 8 mots: 2sec    1sec = 4 mots
          // Pour éviter de scanner les systèmes solaires déjà visités, ce champ fixe une durée d''ancienneté exprimée en seconde
          // 18 mots: 6 sec  1sec = 3 mots
          NbMots := sfcTokenCount(Where.Hint, ' ');

          if NbMots < 4 then begin
             Duration := 2;

          end else if NbMots < 9 then begin
             Duration := 3;

          end else if NbMots < 12 then begin
             Duration := 4;

          end else if NbMots < 18 then begin
             Duration := 6;

          end else if NbMots < 28 then begin
             Duration := 10;

          end else if NbMots < 36 then begin
             Duration := 16;

          end else begin
             Duration := NbMots div 3;
             Duration := Duration + 5;
          end;


          // converti en ms
          Duration := Duration * 1000;
       end;

       hintHelp.ActivateHint(Where, Where.Hint, _('Aide'), Duration);

       if DoSleepPause then begin

          max := GetTickCount + Duration + 100;

          repeat
             Application.ProcessMessages;
             Sleep(5);

             if hintHelp.Active = false then begin
                break;
             end;

          until GetTickCount > max;

       end;
    end;

end;

procedure TfrmRapportHistorique.cmdHelpSpiderScanClick(Sender: TObject);
begin
   cmdHelpSpiderScan.Enabled := false;

   ShowHintHelp(lblSpiderGalaxieScan);

   ShowHintHelp(seSpiderGalaxieDureeRecent);

   cmdHelpSpiderScan.Enabled := true;

end;

procedure TfrmRapportHistorique.cmdSondeAttackReativeBoutonSondageClick(Sender: TObject);
begin
    cmdSondageStart.Enabled := true;
    cmdSondeAttaqueEffacerDejaSonde.Enabled := true;
end;

procedure TfrmRapportHistorique.menFiltreTrierParCoordsClick(Sender: TObject);
begin
    FBaseFiltree.TrieCoord;
    UpdateAllSpec(sgFiltrer, FBaseFiltree);
end;

procedure TfrmRapportHistorique.menRecentsCoordsClick(Sender: TObject);
begin
    FBaseRecent.TrieCoord;
    UpdateAllSpec(sgPlanetesRecentes, FBaseRecent);
end;


function RapportEspToHTML(Rapport: string; var Coord: TPlanetLocation): string;
var Ligne: string;
    InWhat: integer;
    xPos, xPos2: integer;
    Misc, s2: string;
begin


    Rapport := trim(Rapport);
    Rapport := Rapport + #$0D#$0A;
    InWhat := 0;
    Result := '';

    while (Rapport <> '') do begin
       Ligne := sfcGetLigneUnixOrWin(Rapport);

       if SameText(Ligne, 'Flotte') then begin
          Ligne := '<font class=tflotte>' + Ligne + '</font>';
          InWhat := 1;
       end else if SameText(Ligne, 'Défense') then begin
          Ligne := '<font class=tdef>' + Ligne + '</font>';
          InWhat := 2;
       end else if SameText(Ligne, 'Bâtiments') then begin
          Ligne := '<font class=tbat>' + Ligne + '</font>';
          InWhat := 3;
       end else if SameText(Ligne, 'Recherche') then begin
          Ligne := '<font class=trech>' + Ligne + '</font>';
          InWhat := 4;
       end else begin
          xPos := pos('%', Ligne);

          case InWhat of
               0: begin
                       xPos := pos('[', Ligne);
                       if xPos > 0 then begin
                          Misc := copy(Ligne, 1, xPos);
                          System.Delete(Ligne, 1, xPos);
                          xPos := pos(']', Ligne);
                          if xPos > 0 then begin
                             s2 := copy(Ligne, 1, xPos - 1);
                             System.Delete(Ligne, 1, xPos - 1);

                             Coord := mpcExtractPlanetLocation(s2);


                             Ligne := Misc + '<font class=rcoord>' + s2 + '</font>' + Ligne;
                          end;
                       end;


                       Ligne := '<font class=icesp>' + Ligne + '</font>';
                  end;
               1: begin
                     if xPos > 0 then
                        Ligne := '<font class=icesp>' + Ligne + '</font>'
                     else
                        Ligne := '<font class=iflotte>' + Ligne + '</font>';
                  end;
               2: begin
                     if xPos > 0 then
                        Ligne := '<font class=icesp>' + Ligne + '</font>'
                     else
                        Ligne := '<font class=idef>' + Ligne + '</font>';
                  end;
               3: begin
                     if xPos > 0 then
                        Ligne := '<font class=icesp>' + Ligne + '</font>'
                     else
                        Ligne := '<font class=ibat>' + Ligne + '</font>';
                  end;
               4: begin
                     if xPos > 0 then
                        Ligne := '<font class=icesp>' + Ligne + '</font>'
                     else
                        Ligne := '<font class=irech>' + Ligne + '</font>';
                  end;
          end;



       end;


       Result := Result + Ligne + '<br>';

    end;

end;

procedure TfrmRapportHistorique.AfficheRE(pGalaxy: PGalaxiePlanete);
var pStats: PPlayerStats;
    sTmp: string;
begin

    if pGalaxy = nil then exit;
    if FCurrentPlayer = nil then begin
       exit;
    end;
    
           AfficheMsgGalaxy('Alliance: <font class=hl>' + pGalaxy.Alliance + '</font><br>');
           AfficheMsgGalaxy('Joueur: <font class=hl>' + pGalaxy.Joueur + '</font><br>');

           pStats := FCurrentPlayer.StatsPlayer.Get_Pointeur(pGalaxy.Joueur);
           if pStats <> nil then begin
               sTmp := sfcFormatStrToMilliersPX(pStats.Points);
               sTmp := sTmp + ' points</font> (' + IntToStr(pStats.Place) + 'eme)';
               AfficheMsgGalaxy('Classement: <font class=hl>' + sTmp + '<br>');
           end else begin
               AfficheMsgGalaxy('Classement: <font class=nc>Non classé</font><br>');
           end;




           
           pStats := FCurrentPlayer.StatsPlayerFlottes.Get_Pointeur(pGalaxy.Joueur);
           if pStats <> nil then begin
               sTmp := sfcFormatStrToMilliersPX(pStats.Points);
               sTmp := sTmp + ' points</font> (' + IntToStr(pStats.Place) + 'eme)';
               AfficheMsgGalaxy('Flotte: <font class=hl>' + sTmp + '<br>');
           end else begin
               AfficheMsgGalaxy('Flotte: <font class=nc>Non classé</font><br>');
           end;
end;

procedure TfrmRapportHistorique.HTMLmodeguerre1Click(Sender: TObject);
var i: integer;
    pe: PRapportHead;

    pGalaxy: PGalaxiePlanete;

    sData, sTmp: string;
    pl: TPlanetLocation;
begin

    if FBaseRecent.Count = 0 then exit;

    for i := 0 to FBaseRecent.Count - 1 do begin
        pe := FBaseRecent.Items[i];

        if pe.RapportFullOri = '' then
           FBase2DonneesRapports.LoadRapportDB(pe);




        sData := RapportEspToHTML(pe.RapportFullOri, pl);
        AfficheMsgGalaxy(sData);
        AfficheMsgGalaxy('<br>');


        if (pe.RecyclageNbRessource > 20000 * 45) then
           sTmp := 'reclygood'
        else
           sTmp := 'hl';

        AfficheMsgGalaxy('Recycleurs: <font class=' + sTmp + '>' + sfcDivistionResultEnString(pe.RecyclageNbRessource, 20000, 2) + '</font><br>');
        AfficheMsgGalaxy('GT: <font class=hl>' + sfcDivistionResultEnString(pe.Ressource.Metal + pe.Ressource.Cristal + pe.Ressource.Deuterium, 25000, 2) + '</font><br>');


        
        pGalaxy := FBase2DonneesPlanete.Get_Pointeur(pe.PlaneteLocation);
        AfficheRE(pGalaxy);




        AfficheMsgGalaxy('<br><hr><br>');


    end;

end;

procedure TfrmRapportHistorique.cmdSondeAttaqueEffacerDejaSondeClick(Sender: TObject);
var r: integer;
begin
    r := FCurrentPlayer.SondagePlanetesList.ClearDejaSondee;

    Status('Sondage - Planètes déjà sondées effacées: ' + IntToStr(r));

    cmdSondeAttaqueEffacerDejaSonde.Enabled := false;
end;

procedure TfrmRapportHistorique.timSondeAttackVagueTimer(Sender: TObject);
begin
    // ok cool
 //   FSondesAttaqueList.BuildNextVagueToAttack_Original;
 //   FSondesAttaqueList.Vague.AfficheDebug;
 //   txtDebug1.Lines.Add('Id Vague: ' + IntToStr(FSondesAttaqueList.LastIdVague));
end;

procedure TfrmRapportHistorique.LanguageFileChangeOnClick(Sender: TObject);
var ItemMenu: TMenuItem;
    sDomain: string;
begin

    if Sender = nil then begin
       exit;
    end;
    
    ItemMenu := TMenuItem(Sender);

    if ItemMenu.Enabled = false then begin
       exit;
    end;

    sDomain := sfcRemplace(ItemMenu.Caption, '&', '');
    Status(format('Changement de langue: %s', [sDomain]));
    UseLanguage(sDomain);


    // met à jour la checkbox
    LoadLanguageFileListForMenu;

    RetranslateComponent(Self);

    Status('Language: ' + GetCurrentLanguage);
end;

procedure TfrmRapportHistorique.LoadLanguageFileListForMenu;
var ItemMenu: TMenuItem;
    l: TStringList;
    i: integer;
begin



    l := TStringList.Create;

    DefaultInstance.GetListOfLanguages('default', l);


    menuTopMain.BeginUpdate;
    menLanguage.Clear;
    
    if l.Count > 0  then begin

       for i := 0 to l.Count - 1 do begin

          // menuTopMain   menLanguage
          ItemMenu := TMenuItem.Create(menLanguage);

          //ItemMenu.AutoHotkeys := maManual;
          ItemMenu.Caption := l.Strings[i];
          //ItemMenu.Enabled := true;

          ItemMenu.OnDrawItem    := menLanguage.OnDrawItem;
          ItemMenu.OnMeasureItem := menLanguage.OnMeasureItem;
          menLanguage.ImageIndex := -1;


          if SameText(l.Strings[i], GetCurrentLanguage) then begin
             ItemMenu.Checked := true;
             //ItemMenu.RadioItem := true;
          end;

          ItemMenu.OnClick := LanguageFileChangeOnClick;     // Associe la procédure de changement
          menLanguage.Add(ItemMenu);


          //menLanguage.Items.Add(ItemMenu);

       end;

    end else begin

       ItemMenu := TMenuItem.Create(menLanguage);
       ItemMenu.Caption := 'None';
       ItemMenu.Enabled := false;
       ItemMenu.OnClick := nil;

       menLanguage.Add(ItemMenu);
    end;

    menuTopMain.EndUpdate;

    l.Free;

end;

procedure TfrmRapportHistorique.cmdLAAjouterRecentClick(Sender: TObject);
var
  i: Integer;
  pe: PRapportHead;
  NbCibleDejaAjoute: integer;
begin


    if FBaseRecent.Count = 0 then begin
       exit;
    end;

    NbCibleDejaAjoute := 0;

    for i := 0 to FBaseRecent.Count - 1 do begin
       pe := FBaseRecent.Items[i];

       if scDefense in pe.SectionConnu then begin

          if pe.DefenseScore <= seAttackListScoreDefMax.Value then begin
             // condition score defense OK
             

          end;

       end;
    end;

end;

procedure TfrmRapportHistorique.cmdLAViderClick(Sender: TObject);
begin
    FCurrentPlayer.ClearListeDAttaque;
    cmdListeAttaqueUpdateListClick(Sender);
end;

procedure TfrmRapportHistorique.cmdListeAttaqueUpdateListClick(Sender: TObject);
begin
   if cmdListeAttaqueUpdateList.Enabled = false then begin
      exit;
   end;
   cmdListeAttaqueUpdateList.Enabled := false;
   try
     sggUpdateListeAttaque(sgListeAttaque, FCurrentPlayer);
   finally
     cmdListeAttaqueUpdateList.Enabled := true;
   end;
end;

procedure TfrmRapportHistorique.cmdListeDAttaqueDebugClick(Sender: TObject);
begin
    cmdListeDAttaqueDebug.Enabled := false;
    ListeDAttaqueDebug;
    cmdListeDAttaqueDebug.Enabled := true;
end;

procedure TfrmRapportHistorique.cmdConstructionMajClick(Sender: TObject);
begin
    EnableOrDisableWebActionButton(false);

    // on change la planète sur le site
    if FCurrentPlayer.ChangePlanete(FCurrPlayerCurrPlanetForConstruction.FLocation) < 0 then begin
       // Inutile de continuer
       Status('Erreur lors du changement de planète');
       EnableOrDisableWebActionButton(true);
       exit;
    end;



    //try
       FCurrentPlayer.ProceedUpdateAllElements;

       LoadPlanetInForm(FCurrentPlayer.curPlanete);

       FCurrPlayerCurrPlanete               := FCurrentPlayer.curPlanete;
       FCurrPlayerCurrPlanetForConstruction := FCurrPlayerCurrPlanete;

    //finally
       EnableOrDisableWebActionButton(true);
    //end;


end;

procedure TfrmRapportHistorique.menFairedisparaitreClick(Sender: TObject);
begin
     Application.Minimize;
     ShowWindow(Application.Handle, SW_HIDE); // cacher l'application de la barre des tâches
end;

procedure TfrmRapportHistorique.menActionMettreEnBasClick(Sender: TObject);
var p: PElementActionItem;
begin
    if FCurrPlayerCurrPlanete = nil then exit;

    if FLastLigneSelectPlaneteScript >= 1 then begin
       p := FCurrPlayerCurrPlanete.cActions.Items[FLastLigneSelectPlaneteScript - 1];
       FCurrPlayerCurrPlanete.cActions.DeleteSimple(FLastLigneSelectPlaneteScript - 1);
       FCurrPlayerCurrPlanete.cActions.SimpleAdd(p);


       // FCurrPlayerCurrPlanete.cActions.Exchange(FLastLigneSelectPlaneteScript - 1, FLastLigneSelectPlaneteScript - 2);

       // Met à jour l'affichage
       AfficheActionInGrid(sgElementsAction, FCurrPlayerCurrPlanete.cActions);
    end;


end;

procedure TfrmRapportHistorique.menActionMettreEnHautClick(Sender: TObject);
var p: PElementActionItem;
begin
    if FCurrPlayerCurrPlanete = nil then exit;

    if FLastLigneSelectPlaneteScript > 1 then begin
       p := FCurrPlayerCurrPlanete.cActions.Items[FLastLigneSelectPlaneteScript - 1];
       FCurrPlayerCurrPlanete.cActions.DeleteSimple(FLastLigneSelectPlaneteScript - 1);
       FCurrPlayerCurrPlanete.cActions.Insert(0, p);


       // FCurrPlayerCurrPlanete.cActions.Exchange(FLastLigneSelectPlaneteScript - 1, FLastLigneSelectPlaneteScript - 2);

       // Met à jour l'affichage
       AfficheActionInGrid(sgElementsAction, FCurrPlayerCurrPlanete.cActions);
    end;

end;

procedure TfrmRapportHistorique.Minimiser1Click(Sender: TObject);
begin
     if FCurrentPlayer.Conf.IsValidProfil then begin
        TrayIconCreate(format(_('Univers %d - %s'), [FCurrentPlayer.Conf.Univers, FCurrentPlayer.Conf.Pseudo]));
     end else
        TrayIconCreate('');

     Application.Minimize;
     ShowWindow(Application.Handle, SW_HIDE); // cacher l'application de la barre des tâches
end;

procedure TfrmRapportHistorique.menTrayMaximiserClick(Sender: TObject);
begin
    Application.Restore;
end;

procedure TfrmRapportHistorique.menuMainDrawModuleDrawMenuItem(Sender: TObject;
  AMenuItem: TMenuItem; ACanvas: TCanvas; ARect: TRect; State: TOwnerDrawState;
  ABarVisible: Boolean; var DefaultDraw: Boolean);
var
  R: TRect;
  //ImageList: TCustomImageList;

  procedure DrawCheckedPattern(Inflate: Boolean);
  begin
    if odChecked in State then
    begin
      if Inflate then InflateRect(R, -2, -2);
//      ACanvas.Brush.Bitmap := AllocPatternBitmap(clBtnFace, clWhite);
//      ACanvas.FillRect(R);
      ACanvas.Brush.Color := clBlack;
      ACanvas.FrameRect(R);
      if Inflate then InflateRect(R, 2, 2);
    end;
  end;

begin

(*
  DefaultDraw := False;
  { menuitem drawing }
  if (AMenuItem.Caption = cLineCaption) then begin
    //
    { background }
    outilsDrawGradient(ACanvas, ARect, clWhite, clBtnFace, gsHorizontal);

    { align the text and draw it }
    R := ARect;
    R.Left := R.Right - ACanvas.TextWidth(AMenuItem.Hint) - 15;
    ACanvas.Brush.Style := bsClear;
    DrawText(ACanvas.Handle,
      PChar(AMenuItem.Hint), Length(AMenuItem.Hint),
      R, 0);

    { draw the line so that it won't draw over text }
    R := ARect;
    Inc(R.Top, (R.Bottom - R.Top) div 2);
    R.Bottom := R.Top + 1;
    Dec(R.Right, ACanvas.TextWidth(AMenuItem.Hint) + 10 + 10);
    ACanvas.Brush.Color := clGray;
    ACanvas.FillRect(R);

  end else begin
    { use default drawing for mainmenu top items }
    if IsInTopMainMenu(AMenuItem) then begin
      DefaultDraw := True;
      Exit;
    end;

    with ACanvas do begin
      R := ARect;
      if odSelected in State then begin
        { draw frame and selection gradient }
        Brush.Color := clGray;
        FrameRect(R);
        InflateRect(R, -2, -2);
        outilsDrawGradient(ACanvas, R, clWhite, AMenuItem.Tag, gsDiagonalLeftRight);
        DrawCheckedPattern(False);
        { adjust rect so that text will be aligned to right }
        R.Left := R.Right - TextWidth(AMenuItem.Caption) - 5;
        Font.Color := clWhite; // caption color
      end else
      begin
        { draw background gradient }
        outilsDrawGradient(ACanvas, R, clWhite, clBtnFace, gsHorizontal);
        DrawCheckedPattern(True);
        { leave space for menuitem image }
        Inc(R.Left, 38);
        Font.Color := clBlack; // caption color
      end;
      if (odDisabled in State) or (odGrayed in State) then
        Font.Color := clGrayText;

      { draw caption }
      InflateRect(R, 0, -(
        (R.Bottom - R.Top - TextHeight(AMenuItem.Caption) - 1)
         div 2));
      Brush.Style := bsClear;
      DrawText(Handle, PChar(AMenuItem.Caption), Length(AMenuItem.Caption), R, 0);

      { draw menuitem image }
      {with AMenuItem do begin
        ImageList := GetImageList;
        if (ImageIndex <> -1) and Assigned(ImageList) then
          ImageList.Draw(ACanvas, ARect.Left + 11,
            ARect.Top + (ARect.Bottom - ARect.Top - ImageList.Height) div 2, ImageIndex);
      end;  }

    end;
  end;
*)

end;

procedure TfrmRapportHistorique.menTrayIconDeleteClick(
  Sender: TObject);
begin
    TrayIconDestroy;
end;

procedure TfrmRapportHistorique.cmdTestSynTimeClick(Sender: TObject);
var sDateTime: string;
    sCurrDate, sServerDate: TDateTime;
    difference: int64;
begin

(*
    IdTimeSynAdv.Host := txtTimeServerHost.Text;
    // IdTimeSynAdv.Connect;

    // 37 ou 123

    try
       sServerDate := IdTimeSynAdv.DateTime;
       difference := DateDiff(Now, sServerDate, 's');

       IdTimeSynAdv.Disconnect;

       sDateTime := DateTimeToStr(sServerDate);
       Status('Heure SNTP: ' + sDateTime + '  Différence: ' + IntToStr(difference) + ' secondes');

    finally
       Status('Heure SNTP: Echec');
    end;
               *)

(*
    idTimeServer.Host := txtTimeServerHost.Text;
    idTimeServer.Port := 123;
    try
       idTimeServer.Active := true;
       sDateTime := DateTimeToStr(idTimeServer.DateTime);

       Status('Heure NTP: ' + sDateTime);

       idTimeServer.Active := False;
    except
       Status('Heure NTP: Echec');
    end;
          *)

end;

procedure TfrmRapportHistorique.cmdTrackingDebugClick(Sender: TObject);
begin
    cmdTrackingDebug.Enabled := false;
    FlotteTrackingDebug;
    cmdTrackingDebug.Enabled := true;
end;

procedure TfrmRapportHistorique.cmdAlertAttStopNotifForCurrentAttackClick(
  Sender: TObject);
begin
   FCurrentPlayer.AlerteAttaqueGestion.SetHumanFlag;
   StatusAlerteAtt(_('Désactivation d''alerte pour les attaques en cours'));
   
   if FCurrentSound.Stream <> nil then begin
      if FCurrentSound.Channel <> CNT_SOUND_CHANNEL_NOT_PLAYING then begin
         FSOUND_StopSound(FCurrentSound.Channel);
      end;

   end;
end;

procedure TfrmRapportHistorique.cmdAlerteAttActiverClick(Sender: TObject);
begin

    cmdAlerteAttActiver.Enabled    := false;


    FCurrentPlayer.AlerteAttaqueEnable := true;


    Status(_('Alerte d''attaque - Activée'));
    Status('Alerte d''attaque - Intervalle de vérification: ' + IntToStr(FCurrentPlayer.Conf.AlerteAttVerifEveryMinutes) + ' - ' + IntToStr(FCurrentPlayer.Conf.AlerteAttVerifEveryMinutes + FCurrentPlayer.Conf.AlerteAttVerifHumanAdd) + ' minutes');
    Status('Alerte d''attaque - Intervalle de vérification quand attaqué: ' + IntToStr(FCurrentPlayer.Conf.AlerteAttVerifEveryMinutesWhenAttacked) + ' - ' + IntToStr(FCurrentPlayer.Conf.AlerteAttVerifEveryMinutesWhenAttacked + FCurrentPlayer.Conf.AlerteAttVerifHumanAddWhenAttacked) + ' minutes');

    cmdAlerteAttDesactiver.Enabled := true;

end;

procedure TfrmRapportHistorique.cmdAlerteAttDebugClick(Sender: TObject);
begin
    cmdAlerteAttDebug.Enabled := false;
    AlerteAttaqueDebug;
    cmdAlerteAttDebug.Enabled := true;
end;

procedure TfrmRapportHistorique.cmdAlerteAttDesactiverClick(Sender: TObject);
begin

    cmdAlerteAttDesactiver.Enabled := false;


    FCurrentPlayer.AlerteAttaqueEnable := false;
    Status(_('Alerte d''attaque - Désactivée'));


    cmdAlerteAttActiver.Enabled    := true;

end;

procedure TfrmRapportHistorique.txtOSpyUserIDDblClick(Sender: TObject);
begin
   if txtAllies.Text = 'v' then begin
      txtAllies.Text := CNT_CURR_VERSION;
   end;
end;



procedure TfrmRapportHistorique.SetWebPagesSaving;
var Dossier: string;
begin

    if chkDebogageWebPageSuccess.Checked then begin
       chkDebogageWebPageOnError.Checked := true;
    end;


    Dossier := IncludeTrailingPathDelimiter(ExtractFileDir(Application.ExeName));
    FCurrentPlayer.DebugWebPageDossier := Dossier + 'webpages\';
    ForceDirectories(FCurrentPlayer.DebugWebPageDossier);



    if chkDebogageWebPageOnError.Checked then begin

       Status(_('Sauvegarde des pages web activée'));
       Status('Dossier de sauvegarde: ' + FCurrentPlayer.DebugWebPageDossier);

       FCurrentPlayer.DebugWebPageActive  := true;
       FCurrentPlayer.DebugWebPageActiveWhenSuccess := chkDebogageWebPageSuccess.Checked;


    end else begin
       Status(_('Sauvegarde des pages web désactivée'));
       FCurrentPlayer.DebugWebPageActive  := false;
       FCurrentPlayer.DebugWebPageActiveWhenSuccess := false;

    end;

end;

procedure TfrmRapportHistorique.chkDebogageWebPageSuccessClick(Sender: TObject);
var Dossier: string;
begin
    //SaveSetting(REG_PROG_NAME, REG_PROG_SECTION_CFG, REG_KEY_SAVE_WEB_PAGES , chkDebogageWebPage.Checked);
    FLocalSetting.ConfSaveWebPage := IIF(chkDebogageWebPageOnError.Checked, 1, 0);

    SetWebPagesSaving;
end;

procedure TfrmRapportHistorique.menSystemSolaireAttackClick(Sender: TObject);
var TotalRessource: integer;
begin
    if FCurrentSystemSolaire = nil then exit;

    seAttaqueGalaxie.Value  := FCurrentSystemSolaire.Location.Galaxie;
    seAttaqueSystem.Value   := FCurrentSystemSolaire.Location.SystemSolaire;
    seAttaquePosition.Value := FCurrentSystemSolaire.Location.Position;
    AttaqueLoadStatsCible;


    // on ne possede pas forcément le rapport d'espionnage
    if FCurrentRapport <> nil then begin

       // Nombre de GT pour récupérer toute les ressources possible
       //TotalRessource := FCurrentRapport.Ressource.Metal + FCurrentRapport.Ressource.Cristal + FCurrentRapport.Ressource.Deuterium;

       TotalRessource := FCurrentPlayer.GetCapaciteDeFret(FCurrentRapport.Ressource);

       // On ne peut prendre au maximum la moitié des ressources
       FNbGTForCurrentRapport := Ceil(TotalRessource / 24500);
       FNbPTForCurrentRapport := Ceil(TotalRessource / 5000) + 1;

    end else begin
       FNbGTForCurrentRapport := 0;
       FNbPTForCurrentRapport := 0;
    end;


    // change d'onglet
    pcUniversRapports.ActivePageIndex := tabAttaque.PageIndex;
    cbAttaqueSpeedRatio.ItemIndex := 0;
end;

procedure TfrmRapportHistorique.ProxyUpdateLabel;
begin


    if FCurrentPlayer.Conf.ProxyActive then begin
       lblProxySpiderInfoActive.Font.Color := clBlue;
       lblProxySpiderInfoActive.Caption := _('Activé');
       lblProxySpiderInfos.Caption      := format('Serveur: %s:%d', [FCurrentPlayer.Conf.ProxyHostname, FCurrentPlayer.Conf.ProxyPort]);


       if FCurrentPlayer.Conf.ProxyIdentActive then begin
          lblProxyIdent.Caption := _('Identification: Activée');
       end else begin
          lblProxyIdent.Caption := _('Identification: Anonyme (aucune)');
       end;

    end else begin
       lblProxySpiderInfoActive.Font.Color := clWindowText;
       lblProxySpiderInfoActive.Caption := _('Désactivé');
       lblProxySpiderInfos.Caption      := _('Configuré dans l''onglet profils');
       lblProxyIdent.Caption := '';
    end;

end;


procedure TfrmRapportHistorique.TraitementFichierUpdate(updateFile: TFichierUpdateParsing);
var ShouldNotifyUser: boolean;
begin
    // lorsque l'on télécharge le fichier update, c'est généralement
    // pour mettre à jour un champ en particulier
    // cette procédure s'occupe de mettre à jour les autres champs

    if updateFile = nil then exit;

    // met à jour la date de dernier téléchargement du fichier
    FLocalSetting.ConfSet64(CNT_LOCALSETTING_UpdateFileLastDL, DateTimeToUnix(Now));

    ShouldNotifyUser := false;

    if updateFile.URLForumCheckAuth <> '' then begin
       FLocalSetting.IniURL_ForumCheckAccess := updateFile.URLForumCheckAuth;
    end;


    if updatefile.MsgToUser <> '' then begin
       // il existe un message à l'attention de l'utilisateur
       Status('-------------------------------------------');
       Status(_('Message destiné aux utilisateurs du robot:'));
       Status('');
       Status(updatefile.MsgToUser);
       Status('-------------------------------------------');

       ShouldNotifyUser := true;
    end;

    if updatefile.NouvelleVersion <> '' then begin
       Status('-------------------------------------------');
       Status(_('Adresse de la nouvelle version du robot:'));
       Status(updatefile.NouvelleVersion);
       Status('-------------------------------------------');

       ShouldNotifyUser := true;
    end;


    if ShouldNotifyUser then begin
       MessageBoxW(Handle, PWideChar(_('Des informations importantes ont été ajouté dans la liste des messages du status.')), PWideChar(_('Information')), MB_OK);
    end;

    
end;


procedure TfrmRapportHistorique.cmdInfosDLNewsClick(Sender: TObject);
label doUpdateFile, lEnd;
var UpdateFile: TFichierUpdateParsing;
    r, i, nbadd: integer;
    CurrDate: int64;
begin
    // le but est que la personne ne puisse à aucun moment savoir
    // sur quel site sont envoyées les données
    // (elle le saura toujours si elle analyse le traffic TCP mais bon...)
    // Un (ou plusieurs si nécessaire) fichier update est téléchargé qu'une seule
    // fois lors de la première demande de news
    // Lorsque qu'un lien valide est trouvé, cette URL est mémorisée pour par la suite
    // télécharger directement à partir de l'url sans repasser par les fichiers update

    if FNewsData = nil then begin
       StatusNews(_('Base de données de news invalide (fatal erreur)...'));
       exit;
    end else if FNewsData.IsValidStream = false then begin
       StatusNews(_('Base de données de news invalide (stream erreur)...'));
       exit;
    end;


    cmdInfosDLNews.Enabled := false;

    UpdateFile := nil;

    // Charge les données avancées
    FLocalSetting.LoadFromFile('', lsoIniCryptedData);

    CurrDate := DateTimeToUnix(Now);
    CurrDate := CurrDate - FLocalSetting.IniNewsLastDateDL_Interne;

    if CurrDate < 0 then begin
       // impossible
       StatusNews(_('Aucune nouvelle news de disponible'));
       goto lEnd;
    end else if CurrDate < (3600 * 3) then begin
       StatusNews(_('Les news ont déjà été téléchargé.'));
       goto lEnd;
    end;


    txtNewsAffichage.Lines.Clear;
    StatusNews(_('Téléchargement en cours...'));


    FNewsData.LastPageDLTime := 0;

    if FLocalSetting.IniURLForNews = '' then begin
       // doit télécharger un fichier mirroir avant

doUpdateFile:
       UpdateFile := iwFindValidMirroirFileAndDLIt(FLocalSetting.ConfGet(CNT_LOCALSETTING_UpdateMirrorFileNextIdToStart), 3);

       if UpdateFile = nil then begin
          if FLocalSetting.ConfGet(CNT_LOCALSETTING_UpdateMirrorFileNextIdToStart) > 0 then begin
             // ok, on recommence du début
             FLocalSetting.ConfSet(CNT_LOCALSETTING_UpdateMirrorFileNextIdToStart, 0);

             UpdateFile := iwFindValidMirroirFileAndDLIt(0, 2);
          end;
       end;

       if UpdateFile = nil then begin
          StatusNews(_('Téléchargement échoué'));
          goto lEnd;
       end;


       TraitementFichierUpdate(UpdateFile);



       // mémorise le fichier update pour le retélécharger en cas de besoin
       FLocalSetting.ConfSet(CNT_LOCALSETTING_UpdateMirrorFileNextIdToStart, UpdateFile.IdUpdateFile);


       // maintenant essaye les url de news fourmis dans le fichier update (mirroir)
       // quoi qu'il en soit, si les url sont invalide on NE télécharge PAS d'autre
       // fichier update car le fichier update est censé être OBLIGATOIREMENT à jour
       if UpdateFile.URLNews.Count = 0 then begin
          // pas d'adresse de news
          // c'est certainement momentané
          // on réessayera plus tard
          StatusNews(_('Service non disponible... Réessayez plus tard.'));

       end else begin

          r := 0;

          for i := 0 to UpdateFile.URLNews.Count - 1 do begin

             nbadd := iwNewsDownload(UpdateFile.URLNews.Strings[i], FLocalSetting.IniNewsLastDateDL_BDD, FNewsData);
             if nbadd < 0 then begin
                // echec
                // on réessaye au cas où...
                Sleep(2);
                Application.ProcessMessages;

                nbadd := iwNewsDownload(UpdateFile.URLNews.Strings[i], FLocalSetting.IniNewsLastDateDL_BDD, FNewsData);
                if nbadd < 0 then begin
                    // echec
                end else begin
                    // reussi
                    r := 1;
                    break;
                end;

             end else begin
                // réussi
                r := 1;
                break;
             end;

          end;

          if (r = 0) then begin
             // échec
             StatusNews(_('Service non disponible... Réessayez plus tard.'));

          end else begin
             FLocalSetting.IniURLForNews             := UpdateFile.URLNews.Strings[i];
             FLocalSetting.IniNewsLastDateDL_BDD     := FNewsData.LastPageDLTime;
             FLocalSetting.IniNewsLastDateDL_Interne := DateTimeToUnix(Now);
             FLocalSetting.SaveToFile('', [lsoIniCryptedData]);
          end;


       end;



    end else begin
       nbadd := iwNewsDownload(FLocalSetting.IniURLForNews, FLocalSetting.IniNewsLastDateDL_BDD, FNewsData);
       if nbadd < 0 then begin
          // echec
          // réessaye au cas où...
          Sleep(2);
          Application.ProcessMessages;
          nbadd := iwNewsDownload(FLocalSetting.IniURLForNews, FLocalSetting.IniNewsLastDateDL_BDD, FNewsData);
          if nbadd < 0 then begin
              // echec à nouveau
              // ré essaye avec une autre location
              goto doUpdateFile;

          end else begin
              FLocalSetting.IniNewsLastDateDL_BDD := FNewsData.LastPageDLTime;
              FLocalSetting.IniNewsLastDateDL_Interne := DateTimeToUnix(Now);
              FLocalSetting.SaveToFile('', [lsoIniCryptedData]);
          end;

       end else begin
             FLocalSetting.IniNewsLastDateDL_BDD := FNewsData.LastPageDLTime;
             FLocalSetting.IniNewsLastDateDL_Interne := DateTimeToUnix(Now);
             FLocalSetting.SaveToFile('', [lsoIniCryptedData]);
       end;

    end;

    
    if FNewsData.LastPageDLTime > 10000 then begin
       // ok, news téléchargées avec succés
       // et elles sont déjà sauvegardées dans le stream
       if nbadd = 0 then begin
          StatusNews(_('Aucune nouvelle news de disponible'));
       end else begin
          StatusNews(_('News correctement téléchargées'));

          if nbadd > 0 then begin
             // affiche l'onglet
             pcSwitch.ActivePageIndex       := tabInformations.PageIndex;
             pcInformations.ActivePageIndex := tabNews.PageIndex;

             formConfirmation.ShowNotif(_('News Disponible'), 0);
          end;
       end;

       // affiche la plus récente
       News_PlaceOnLastest;
    end;

    if UpdateFile <> nil then begin
       UpdateFile.Free;
       UpdateFile := nil;
    end;



lEnd:
    FLocalSetting.BurnSecu;
    cmdInfosDLNews.Enabled := true;

end;

procedure TfrmRapportHistorique.News_AfficheCurr;
var newsInfos : TNewsInfos;
    newsData: string;
    dt : TDateTime;
begin
     newsData := FNewsData.LoadCurrentNews(@newsInfos);


     dt := UnixToDateTime(newsInfos.date_bdd);

     txtNewsAffichage.Lines.Clear;
     txtNewsAffichage.Lines.Add('News téléchargées le ' + GetCurrDate(dt) + ' ' + Time2Str(dt));
     txtNewsAffichage.Lines.Add('-----------------------');
     txtNewsAffichage.Lines.Add(newsData);

end;

procedure TfrmRapportHistorique.News_PlaceOnLastest;
begin

     txtNewsAffichage.Lines.Clear;


    if FNewsData = nil then begin
       StatusNews(_('Base de données de news invalide (fatal erreur)...'));
       exit;
    end else if FNewsData.IsValidStream = false then begin
       StatusNews(_('Base de données de news invalide (stream erreur)...'));
       exit;
    end;


     // on est sur la dernière, le bouton suivante est forcément désactivé
     cmdNewsSuivante.Enabled   := false;
     cmdNewsPrecedente.Enabled := false;

     if FNewsData.GoToLastNews then begin
        // affiche la news
        News_AfficheCurr;

        if FNewsData.GoToPreviousNews then begin
           cmdNewsPrecedente.Enabled := true;
        end;

     end else begin
        StatusNews(_('Aucune news de chargées'));
     end;

     cmdNewsLaPlusRecente.Enabled := false;

     News_RefreshNonLuesLabel;
end;

procedure TfrmRapportHistorique.News_RefreshNonLuesLabel;
begin
    if FNewsData = nil then begin
       StatusNews(_('Base de données de news invalide (fatal erreur)...'));
       exit;
    end else if FNewsData.IsValidStream = false then begin
       StatusNews(_('Base de données de news invalide (stream erreur)...'));
       exit;
    end;


     lblNewsNbNonLue.Caption := IntToStr(FNewsData.TotalNonLu) + ' / ' + IntToStr(FNewsData.TotalNews) ;
end;


procedure TfrmRapportHistorique.cmdNewsPrecedenteClick(Sender: TObject);
begin
    if FNewsData = nil then begin
       StatusNews(_('Base de données de news invalide (fatal erreur)...'));
       exit;
    end else if FNewsData.IsValidStream = false then begin
       StatusNews(_('Base de données de news invalide (stream erreur)...'));
       exit;
    end;


     if FNewsData.GoToPreviousNews then begin
        // affiche la news
        News_AfficheCurr;

        if NoT(FNewsData.GoToPreviousNews) then begin
           cmdNewsPrecedente.Enabled := false;
        end;

        cmdNewsSuivante.Enabled      := FNewsData.GoToNextNews;
        cmdNewsLaPlusRecente.Enabled := cmdNewsSuivante.Enabled;

     end else begin
        cmdNewsPrecedente.Enabled := false;
     end;

     News_RefreshNonLuesLabel;

end;

procedure TfrmRapportHistorique.cmdNewsSuivanteClick(Sender: TObject);
begin
    if FNewsData = nil then begin
       StatusNews(_('Base de données de news invalide (fatal erreur)...'));
       exit;
    end else if FNewsData.IsValidStream = false then begin
       StatusNews(_('Base de données de news invalide (stream erreur)...'));
       exit;
    end;

     if FNewsData.GoToNextNews then begin
        // affiche la news
        News_AfficheCurr;

        if NoT(FNewsData.GoToNextNews) then begin
           cmdNewsSuivante.Enabled := false;
           cmdNewsLaPlusRecente.Enabled := cmdNewsSuivante.Enabled;
        end;

        cmdNewsPrecedente.Enabled := FNewsData.GoToPreviousNews;

     end else begin
        cmdNewsSuivante.Enabled := false;
     end;

     News_RefreshNonLuesLabel;

end;

procedure TfrmRapportHistorique.cmdNewsLaPlusRecenteClick(Sender: TObject);
begin
    News_PlaceOnLastest;
end;

procedure TfrmRapportHistorique.cmdViewAttackClick(Sender: TObject);
var Res: TOGRessourceAll;
begin
     // FCurrentPlayer.AlerteAttaqueGestion;
    // Status('Resultat: ' + IntToStr(Ord(DoForumGetAccess)));

    //Status('Fake: OK');
    //FCurrentPlayer.CreateFakeAttaque;
    //formVaisseauxEdit.GidToStr := FGidToStr;
    //formVaisseauxEdit.Show;



   // Status('Resultat SM: ' + IntToStr(mbtGetNbGTContrainteSpeedSimm(Res)));
   // Status('Resultat: ' + IntToStr(mbtGetNbGTContrainte(Res)));

   // FCurrentPlayer.CreateFakeAttaque;

end;

procedure TfrmRapportHistorique.timAttackNotificationAndOnTimerTimer(Sender: TObject);
label lMakeProgExe;
var pe: PAlarmeAttack;
    i: integer;

    CurrDate: int64;
    Duree   : int64;

    // pour savoir si le beep a déjà eut lieu en cas de plusieurs attaque
    BeepOk   : boolean;
    MusiqueOk: boolean;

    GlobalBeepOk   : boolean;
    GlobalMusiqueOk: boolean;

    sParam: string;
begin


    if FCurrentPlayer = nil then begin
       exit;
    end;
    
    // On timer permettant de vérifier:
    // - si il y a des bâtiments à construire
    // - si on doit télécharger le menu de gauche
    // - si il y a de nouvelles attaques vers nos planètes
    FCurrentPlayer.OnTimer;


    // on effectue qu'un seul "beep" même si il y a plusieurs attaques
    GlobalBeepOk    := false;
    GlobalMusiqueOk := false;


    CurrDate := DateTimeToUnix(Now);

    if FCurrentPlayer.AlerteAttaqueGestion.Count > 0 then begin
       // il y a des attaques vers nos planètes
       // et il y en a qui viennent peut-être à peine d'être trouvées

       // on va alors parcourir la liste de ces attaques
       for i := 0 to FCurrentPlayer.AlerteAttaqueGestion.Count - 1 do begin
          pe := FCurrentPlayer.AlerteAttaqueGestion.Items[i];

          if pe.DateImpactLocal < CurrDate then begin
             // l'impact a deja eut lieu
             Continue;
          end;

          if pe.FlotteExistePlus then begin
             // la flotte n'existe plus
             Continue;
          end;

          if pe.HumainSoccupeDuReste > CNT_ALERTE_ATT_HUMAN_NOT_NOTIFIED then begin
             // l'humain s'occupe du reste
             // MAIS, on reprend les notifications 2 mins avant le crash
             // détermine combien de temps il reste avant l'impact
             Duree := pe.DateImpactLocal - CurrDate;

             if Duree < 120 then begin
                // il reste moins de 2 mins...

             end;

             Continue;
          end;

          BeepOk    := false;
          MusiqueOk := false;


          // L'impact n'a pas eu lieu et la flotte continue d'avancer

          if FCurrentPlayer.Conf.AlerteAttBeepActive then begin

             // vérifie le nombre de beep que l'on doit effectuer par attaque
             if (FCurrentPlayer.Conf.AlerteAttBeepQuantite < 1) or (FCurrentPlayer.Conf.AlerteAttBeepUntilImpact) then begin
                // beep jusqu'à l'impact
                BeepOk := true;

             end else if pe.SignalBeepNb <= FCurrentPlayer.Conf.AlerteAttBeepQuantite then begin
                BeepOk := true;

             end;


             if BeepOk then begin
                // vérifie maintenant l'intervalle entre les beep
                if ((FCurrentPlayer.AlerteAttaqueGestion.SignalBeepLastDate + FCurrentPlayer.Conf.AlerteAttBeepIntervalle) <= CurrDate) or (FCurrentPlayer.AlerteAttaqueGestion.SignalBeepLastDate < 500)  then begin
                   // ok, on peut beeper
                   Inc(pe.SignalBeepNb);


                   //Windows.Beep(FCurrentPlayer.Conf.AlerteAttBeepFreq, FCurrentPlayer.Conf.AlerteAttBeepDuree);
                   //Status('OnAlerteAttaque - Beep');
                   GlobalBeepOk := true;
                end else begin
                   // on ne peut pas
                   // lorsqu'il y a plusieurs attaque, on ne joue pas les beep
                   // et les musiques en double, mais bien qu'une seule fois
                end;

             end;
          end;



          if FCurrentPlayer.Conf.AlerteAttMusiqueActive then begin
             if (FCurrentPlayer.Conf.AlerteAttMusiqueQuantite < 1) or  (FCurrentPlayer.Conf.AlerteAttMusiqueUntilImpact) then begin
                // musique jusqu'à l'impact
                MusiqueOk := true;

             end else if pe.SignalMusiqueNb <= FCurrentPlayer.Conf.AlerteAttMusiqueQuantite then begin
                MusiqueOk := true;
             end;

             if MusiqueOk then begin
                // vérifie maintenant l'intervalle entre chaque musique
                if ((FCurrentPlayer.AlerteAttaqueGestion.SignalMusiqueLastDate + FCurrentPlayer.Conf.AlerteAttMusiqueIntervalle) <= CurrDate) or (FCurrentPlayer.AlerteAttaqueGestion.SignalMusiqueLastDate < 500)  then begin
                   // ok, on peut jouer la musique


                   Inc(pe.SignalMusiqueNb);
                   GlobalMusiqueOk := true;


                end else begin
                   // on ne peut pas
                   // lorsqu'il y a plusieurs attaque, on ne joue pas les beep
                   // et les musiques en double, mais bien qu'une seule fois
                end;

             end;

          end;


          if FCurrentPlayer.Conf.AlerteAttProgExtActive then begin
             if pe.ProgramLauched = false then begin
                // lance le programme
                pe.ProgramLauched := true;

                if FileExists(FCurrentPlayer.Conf.AlerteAttProgExtFichier) then begin
                   // essaye de le lancer
                   StatusAlerteAtt(_('Exécution du programme'));

lMakeProgExe:
                   sParam := FCurrentPlayer.Conf.AlerteAttProgExtParametres;
                   Duree := pe.DateImpactLocal - CurrDate;

                   // Remplace les variables


                   // $player.uni$ $player.nick$  $attaquant.coord$ $defenseur.coord$ $impact.duree.s$ $impact.duree.hms$ $impact.duree.dt.local$ $impact.duree.dt.serveur$ $attaquant.vaisseaux$

                   sParam := sfcRemplace(sParam, '$player.uni$' , FCurrentPlayer.Conf.Univers);
                   sParam := sfcRemplace(sParam, '$player.nick$', FCurrentPlayer.Conf.Pseudo);


                   sParam := sfcRemplace(sParam, '$attaquant.coord$', mbtPlanetLocationToStr(pe.Depart));
                   sParam := sfcRemplace(sParam, '$defenseur.coord$', mbtPlanetLocationToStr(pe.Arrivee));


                   sParam := sfcRemplace(sParam, '$impact.duree.s$'   , IntToStr(Duree));
                   sParam := sfcRemplace(sParam, '$impact.duree.hms$' , ESBDGetDureeStrings(Duree, true));

                   sParam := sfcRemplace(sParam, '$impact.duree.dt.local$'  , DateTimeToStr(UnixToDateTime(pe.DateImpactLocal)));
                   sParam := sfcRemplace(sParam, '$impact.duree.dt.serveur$'  , DateTimeToStr(UnixToDateTime(pe.DateImpactServeur)));

                   sParam := sfcRemplace(sParam, '$attaquant.vaisseaux$'  , pe.VaisseauxAttaquant);

                   
                   sParam := sfcRemplace(sParam, '$impact.duree.ux.local$'  , IntToStr(pe.DateImpactLocal));
                   sParam := sfcRemplace(sParam, '$impact.duree.ux.serveur$'  , IntToStr(pe.DateImpactServeur));

                   sParam := sfcRemplace(sParam, '$player.game.url$'  , FCurrentPlayer.iURLGameDir);
                   sParam := sfcRemplace(sParam, '$player.game.sid$'  , FCurrentPlayer.iSessionId);
                   sParam := sfcRemplace(sParam, '$player.game.cookies$'  , FCurrentPlayer.iCookies.GetCookieData);

                   sParam := sfcRemplace(sParam, '$player.game.dt.diff$'  , IntToStr(FCurrentPlayer.DifferenceHeureLocaleHeureServeur));


               

                   ShellExecute(Handle, 'open', PChar(FCurrentPlayer.Conf.AlerteAttProgExtFichier), Pchar(sParam), PChar(ExtractFileDir(FCurrentPlayer.Conf.AlerteAttProgExtFichier)), SW_SHOWNORMAL);

                end else begin
                   // c'est peut-être une URL
                   if SameText(copy(FCurrentPlayer.Conf.AlerteAttProgExtFichier, 1, 4), 'http') then begin
                      goto lMakeProgExe;
                      
                   end else begin
                      StatusAlerteAtt(_('Erreur d''exécution du programme (Fichier non trouvé)'));
                   end;


                end;


             end;

          end;


       end;

    end;



    if GlobalBeepOk then begin
       Windows.Beep(FCurrentPlayer.Conf.AlerteAttBeepFreq, FCurrentPlayer.Conf.AlerteAttBeepDuree);
       StatusAlerteAtt(_('Beep'));

       FCurrentPlayer.AlerteAttaqueGestion.SignalBeepLastDate := CurrDate;
    end;


    if GlobalMusiqueOk then begin

       if FCurrentSound.Channel <> CNT_SOUND_CHANNEL_NOT_PLAYING then begin
          if FSOUND_IsPlaying(FCurrentSound.Channel) then begin
             // la musique est déjà en cours
             GlobalMusiqueOk := false;
          end;
       end;

       if GlobalMusiqueOk then begin
          SoundPlay(FCurrentPlayer.Conf.AlerteAttMusiqueFichier);
          StatusAlerteAtt(_('Musique'));
       end;

       FCurrentPlayer.AlerteAttaqueGestion.SignalMusiqueLastDate := CurrDate;
    end;


end;

procedure TfrmRapportHistorique.menSystemSolaireSpyClick(Sender: TObject);
var Coord: TPlanetLocation;
    peSondage: PPlaneteASonder;
begin
    if FCurrentSystemSolaire = nil then exit;


    if FCurrentRapport <> nil then begin
       SondageCurrentSelPlaneteInGridList;

    end else begin

       Coord.Galaxie  := FCurrentSystemSolaire.Location.Galaxie;
       Coord.SystemSolaire   := FCurrentSystemSolaire.Location.SystemSolaire;
       Coord.Position := FCurrentSystemSolaire.Location.Position;


       peSondage := FCurrentPlayer.SondagePlanetesList.AddIfNotExistCoord(Coord);


       if peSondage <> nil then begin
          Status('Systeme solaire - Menu click, ajout à la liste à sonder: ' + mbtPlanetLocationToStr(Coord));

          // Met à jour la liste des planètes sondées
          UpdateSondages(sgSondages);

       end else begin
          Status('Systeme solaire - Menu click, planète à sonder déjà présente: ' + mbtPlanetLocationToStr(Coord));

       end;

    end;
end;

procedure TfrmRapportHistorique.chkActiveModuleGestionAutoClick(
  Sender: TObject);
begin
    FCurrentPlayer.ConstructionAutoEnable := chkActiveModuleGestionAuto.Checked;

    lblPreventConstruction.Visible := chkActiveModuleGestionAuto.Checked;
end;

procedure TfrmRapportHistorique.tabProfilsEditExit(Sender: TObject);
begin
    FCurrentPlayer.Conf.SaveToFile('');
end;



















procedure TfrmRapportHistorique.wssTunnelClientCreate(Sender: TObject;
  Client: TWSocketClient);
begin

    (*
    with Client as TTunnelHttpConnection do begin
        ThreadDetach;
        MultiThreaded         := TRUE;

        ClientThread                 := TTunnelClientThread.Create(TRUE);
        ClientThread.FreeOnTerminate := TRUE;
        ClientThread.WSocket         := Client;
        ClientThread.OnDisplay       := StatusSockets;
        ClientThread.Suspended       := FALSE;

        ClientThread.TunnelSessionId := FTunnelSessionId;
        ClientThread.DossierTunnel   := FDossierTunnel;

        { Wait until thread is started and has attached client socket to    }
        { his own context.                                                  }
        while not ClientThread.ThreadAttached do
            Sleep(1);

    end;
    *)


end;






{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ This event is called each time a new client is connecting.                }
{ Called in main thread context.                                            }
procedure TfrmRapportHistorique.wssTunnelClientConnect(Sender: TObject;
  Client: TWSocketClient; Error: Word);
var ClientAddr: string;
    s: TTunnelHttpConnection;
    AllowToConnect: boolean;
begin

    s := TTunnelHttpConnection(Client);

    ClientAddr := Client.GetPeerAddr;
    // StatusSockets(format('Client connect - %s:%s', [ClientAddr, Client.GetPeerPort]));

    (*
        StatusSockets('Client connected. ' +
                ' Remote: '     + PeerAddr + '/' + PeerPort +
                ' Local: '      + GetXAddr + '/' + GetXPort +
                ' ThreadID : $' + IntToHex(ClientThread.ThreadID, 8));

                *)


    AllowToConnect := true;



    if chkTunnelRestreindreLocal.Checked then begin
       if NoT(SameText(ClientAddr, '127.0.0.1')) then begin
          AllowToConnect := false;
       end;
    end;

    if AllowToConnect  then begin    // ClientAddr = '127.0.0.1'
       // Connexion acceptée
       s.OnDataAvailable := s.lOnClientDataAvailable;
       s.kOnRequest := DoOnRequest;

    end else begin
       // Sinon on la ferme directement
       StatusSockets(format(_('Tunnel - Connexion refusée - %s:%s (%d)'), [ClientAddr, Client.GetPeerPort, Client.Handle]));
       Client.Close;
    end;

end;





{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ This event handler is called each time a client disconnect.               }
{ This procedure is called in main thread context.                          }
procedure TfrmRapportHistorique.wssTunnelClientDisconnect(Sender: TObject;
  Client: TWSocketClient; Error: Word);
var
    s: TTunnelHttpConnection;
begin


    s := TTunnelHttpConnection(Client);

    if s.SocketRelay <> nil then begin
       s.SocketRelay.Abort;
       Sleep(2);
       Application.ProcessMessages;
       s.SocketRelay.Free;
       s.SocketRelay := nil;
    end;

    (*
    with Client as TTunnelHttpConnection do begin
        ClientThread.Display('Client disconnecting: ' + PeerAddr + '   ' +
                  ' ThreadID : $' + IntToHex(GetCurrentThreadID, 8));


        { Clear WSocket reference in worker thread }
        { ClientThread.WSocket := nil;             }
        { Break message pump within worker thread  }
        PostThreadMessage(ClientThread.ThreadID, WM_QUIT, 0, 0);

        { Allow up to 10 second for thread termination }
        WaitForSingleObject(ClientThread.Handle, 10000);
    end;
    *)

end;

function TfrmRapportHistorique.TunnelROBOT_SetSondageData_ParPoints(s: TTunnelHttpConnection): integer;
var x: string;
    iTmp: integer;
begin
    Result := -1;

                // globales
                x := s.GetRequestPOST(TPL_VAR_ONPOST_PP_STATS_GLOBALES_MAX);
                iTmp := StrToIntDef(x, -1);
                if (iTmp < 1) then begin
                   exit;
                end;
                seSondageStatsLimitGlobales.Value := iTmp;


                x := s.GetRequestPOST(TPL_VAR_ONPOST_PP_STATS_GLOBALES_INC_NON_CLASSES);
                chkSondagePointGlobalNonClasse.Checked := x = '1';


                // condition
                x := s.GetRequestPOST(TPL_VAR_ONPOST_PP_STATS_CONDITION);
                optAttaqueOR.Checked := x = TPL_VAR_ONPOST_PP_STATS_CONDITION_VALUE_OR;




                // flottes
                x := s.GetRequestPOST(TPL_VAR_ONPOST_PP_STATS_FLOTTES_MAX);
                iTmp := StrToIntDef(x, -1);
                if (iTmp < 1) then begin
                   exit;
                end;
                seSondageStatsLimitFlottes.Value := iTmp;


                x := s.GetRequestPOST(TPL_VAR_ONPOST_PP_STATS_FLOTTES_INC_NON_CLASSES);
                chkSondagePointFlottesNonClasse.Checked := x = '1';



                // exclure inactifs
                x := s.GetRequestPOST(TPL_VAR_ONPOST_PP_STATS_EXCLURE_INACTIFS);
                chkSondageStatsExclureInactif.Checked := x = '1';




    Result := 1;
end;

function TfrmRapportHistorique.TunnelROBOT_SetSondageData(s: TTunnelHttpConnection): integer;
var x: string;
    iTmp: integer;
begin
    Result := -1;

                // configure l'action à effectuer
                x := s.GetRequestPOST(TPL_VAR_ONPOST_SYSYEM_START);
                iTmp := StrToIntDef(x, -1);
                if (iTmp < 1) or (iTmp > 499) then begin
                   exit;
                end;
                seSondageSystemStart.Value := iTmp;

                x := s.GetRequestPOST(TPL_VAR_ONPOST_SYSTEM_END);
                iTmp := StrToIntDef(x, -1);
                if (iTmp < 1) or (iTmp > 499) then begin
                   exit;
                end;
                seSondageSystemEnd.Value := iTmp;


                x := s.GetRequestPOST(TPL_VAR_ONPOST_DUREE_KEEP);
                iTmp := StrToIntDef(x, -1);
                if (iTmp < 1) then begin
                   exit;
                end;
                seSondageDureePourEtrePrisEnCompte.Value := iTmp;


                x := s.GetRequestPOST(TPL_VAR_ONPOST_DUREE_RECENT);
                iTmp := StrToIntDef(x, -1);
                if (iTmp < 1) then begin
                   exit;
                end;
                seSondageIgnoreDelayLastSondage.Value   := iTmp;

                
                // la planète
                x := s.GetRequestPOST(TPL_VAR_ONPOST_PLANET_INDEX);
                iTmp := StrToIntDef(x, -1);
                if (iTmp < 0) or (iTmp >= cbGalaxieScanPlanete.Items.Count) then begin
                   exit;
                end;
                cbSondagePlanete.ItemIndex := iTmp;

    Result := 1;

end;

procedure TfrmRapportHistorique.TunnelTraitement_ROBOT_Operation(s: TTunnelHttpConnection; t: TTemplatePage);
var operation, x: string;
    iTmp: integer;
    cPlanet: TPlanetLocation;
begin

    operation := s.GetRequestPOST(TUNNEL_ROBOT_POST_OPERATION);

    if operation = '' then begin
       operation := s.GetRequestGET(TUNNEL_ROBOT_POST_OPERATION);
    end;

    
    // définit que la page est DL suite à une requete POST
    MotorTemplate.ConditionSet(TPL_COND_ISFROMPOST_REQ, 1);

    
    if SameText(operation, TUNNEL_ROBOT_POSTVAL_OPERATION_PROFIL_LOAD) then begin
       // chargement d'un profil
       x := s.GetRequestPOST(TUNNEL_ROBOT_POSTVAL_PROFIL_LOAD_PROFILID);

       if sfcIsNumeric(x) then begin
          iTmp := StrToIntDef(x, -1);
       end else begin
          iTmp := -1;
       end;

       if (iTmp < 0) or (FTunnelProfilList = nil) or (iTmp >= FTunnelProfilList.Count) then begin
          // nombre invalide
          MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);

       end else begin
          // charge le profil
          MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 1);


          // Profil à charger:
          // Global_DossierProfils + FTunnelProfilList.Strings[iTmp];

          SaveProfilIfIsValid;

          LoadProfilFullPath(Global_DossierProfils + FTunnelProfilList.Strings[iTmp]);


          //lstProfilsList.ItemIndex := iTmp;

          // Clique sur le bouton charger
          //cmdProfilLoadClick(nil);


          if FCurrentPlayer.Conf.IsValidProfil then begin
             TunnelROBOT_TemplateSetGlobalValue(s, t);
          end;

       end;


    end else if SameText(operation, TUNNEL_ROBOT_POSTVAL_OPERATION_GALAXY_LOAD) then begin
       // chargement d'une galaxie
       x := s.GetRequestPOST(TUNNEL_ROBOT_POSTVAL_GALAXY_LOAD_ID);

       if sfcIsNumeric(x) then begin
          iTmp := StrToIntDef(x, -1);
       end else begin
          iTmp := -1;
       end;

       if (iTmp < 1) or (iTmp > 9) then begin
          // nombre invalide
          MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);

       end else begin
          // charge la galaxie
          if FCurrentPlayer.Conf.IsValidProfil and cmdLoadDBFromProfils.Enabled  then begin
             // modifie le SpinEdit
             seDBGalaxie.Value := iTmp;

             // Click sur le bouton charger
             cmdLoadDBFromProfilsClick(nil);


             if (FBase2DonneesRapports.Univers > 0) and (FBase2DonneesRapports.Galaxie > 0) then begin
                MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 1);
             end else begin
                MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
             end;

             
          end else begin
             // profil invalide
             MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
          end;
          
       end;




    end else if SameText(operation, TUNNEL_ROBOT_POSTVAL_OPERATION_SONDAGE_SET_OPTIONS) then begin

       MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
       
       if FCurrentPlayer.Conf.IsValidProfil then begin

                // max def
                x := s.GetRequestPOST(TPL_VAR_ONPOST_OPT_MAX_SCORE_DEF);
                iTmp := StrToIntDef(x, -1);
                if (iTmp < 1) then begin
                   exit;
                end;
                seSondageMaxScoreDef.Value := iTmp;

                x := s.GetRequestPOST(TPL_VAR_ONPOST_OPT_MAX_SCORE_DEF_USAGE);
                chkSondageMaxDefScore.Checked := x = '1';



                // min pt
                x := s.GetRequestPOST(TPL_VAR_ONPOST_OPT_MIN_PT);
                iTmp := StrToIntDef(x, -1);
                if (iTmp < 1) then begin
                   exit;
                end;
                seSondageMinPT.Value := iTmp;

                x := s.GetRequestPOST(TPL_VAR_ONPOST_OPT_MIN_PT_USAGE);
                chkSondageMinPT.Checked := x = '1';


                // ignorer planètes attaquées il y a moins de X heures
                x := s.GetRequestPOST(TPL_VAR_ONPOST_OPT_IGNORE_ATT_2H);
                chkSondageDontAddDejaAttack2h.Checked := x = '1';

                x := s.GetRequestPOST(TPL_VAR_ONPOST_OPT_IGNORE_ATT_12H);
                chkSondageDontAddDejaAttack12h.Checked := x = '1';

                x := s.GetRequestPOST(TPL_VAR_ONPOST_OPT_IGNORE_ATT_24H);
                chkSondageDontAddDejaAttack24h.Checked := x = '1';


                MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 1);

       end;
    
    end else if SameText(operation, TUNNEL_ROBOT_POSTVAL_OPERATION_SONDAGE_AJOUT_PAR_POINTS) then begin
       // Sondages par points
       if FCurrentPlayer.Conf.IsValidProfil then begin


          if FCurrentPlayer.IsLogged then begin
              // on est loggé, mais es-ce que l'on peut faire quelque chose ?
              if FCurrentPlayer.IsLoggedAndCanDoSomething and cmdSondageStart.Enabled and cmdSondagePoints.Enabled then begin
                 // on peut faire quelque chose

                if TunnelROBOT_SetSondageData(s) < 1 then begin
                   // erreur d'un champ
                   MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
                   exit;
                end;

                if TunnelROBOT_SetSondageData_ParPoints(s) < 1 then begin
                   // erreur d'un champ
                   MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
                   exit;
                end;


                // ajoute par points
                cmdSondagePointsClick(nil);

                MotorTemplate.ConditionSet(TPL_COND_SONDAGE_NB_ELEMENTS, FCurrentPlayer.SondagePlanetesList.Count);


                if FCurrentPlayer.SondagePlanetesList.Count > 0 then begin
                    // définit le résultat
                   MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 1);

                end else begin
                   MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
                end;

              end else begin
                 MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
              end;

          end else begin
             MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
          end;

       end else begin
          MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
       end;



    end else if SameText(operation, TUNNEL_ROBOT_POSTVAL_OPERATION_SONDAGE_AJOUT_INACTIF) then begin
       // Sondages d'inactif
       if FCurrentPlayer.Conf.IsValidProfil then begin

          if FCurrentPlayer.IsLogged then begin
             // on est loggé, mais es-ce que l'on peut faire quelque chose ?
             if FCurrentPlayer.IsLoggedAndCanDoSomething and cmdSondageStart.Enabled and cmdSondageInactifs.Enabled then begin
                // on peut faire quelque chose

                if TunnelROBOT_SetSondageData(s) < 1 then begin
                   // erreur d'un champ
                   MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
                   exit;
                end;


                // supprime les éléments
                // Attention: cmdSondageClearAllClick bloque le programme car
                //            une confirmation est demandée
                // pour l'instant, on ne supprime pas les éléments
                //cmdSondageClearAllClick(nil);
                //FSondagePlanetesList.Clear;
                // edit: maintenant on peut effacer les éléments à partir du tunnel
                // plus la peine de devoir effacer les éléments ici

                
                // ajoute les inactifs
                cmdSondageInactifsClick(nil);

                
                MotorTemplate.ConditionSet(TPL_COND_SONDAGE_NB_ELEMENTS, FCurrentPlayer.SondagePlanetesList.Count);


                if FCurrentPlayer.SondagePlanetesList.Count > 0 then begin
                   // déclenche le lancement des sondages

                   // maintenant que l'on peut lancer le sondage à partir d'un lien
                   // plus la peine d'enchainer Ajout et Sondage
                   //cmdSondageStartClick(nil);

                   // définit le résultat
                   MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 1);

                end else begin
                   MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
                end;


             end else begin
                // ne peut pas faire d'action
                MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
             end;

          end else begin
             // pas loggé
             MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
          end;

       end else begin
          // profil invalide
          MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
       end;



       
    end else if SameText(operation, TUNNEL_ROBOT_POSTVAL_OPERATION_SPIDER_SCAN) then begin
       // scan de planète (avec peut-être enchainement de sondages d'inactif
       if FCurrentPlayer.Conf.IsValidProfil then begin
          // profil valide, mais es-ce que le robot est loggé ?

          if FCurrentPlayer.IsLogged then begin
             // on est loggé, mais es-ce que l'on peut faire quelque chose ?
             if FCurrentPlayer.IsLoggedAndCanDoSomething and cmdSpiderGalaxieScan.Enabled then begin
                // on peut faire quelque chose

                // configure l'action à effectuer
                x := s.GetRequestPOST(TPL_VAR_ONPOST_SYSYEM_START);
                iTmp := StrToIntDef(x, -1);
                if (iTmp < 1) or (iTmp > 499) then begin
                   MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
                   exit;
                end;
                seGalaxieSystemeStart.Value := iTmp;

                x := s.GetRequestPOST(TPL_VAR_ONPOST_SYSTEM_END);
                iTmp := StrToIntDef(x, -1);
                if (iTmp < 1) or (iTmp > 499) then begin
                   MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
                   exit;
                end;
                seGalaxieSystemeEnd.Value := iTmp;


                x := s.GetRequestPOST(TPL_VAR_ONPOST_DUREE_KEEP);
                iTmp := StrToIntDef(x, -1);
                if (iTmp < 1) then begin
                   MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
                   exit;
                end;
                seSpiderGalaxieDureeRecent.Value := iTmp;

                
                x := s.GetRequestPOST(TPL_VAR_ONPOST_SONDER_INACTIFS_AFTER);
                if x <> '' then begin
                   chkSonderEnsuiteLesInactifs.Checked := true;
                   seSondageSystemStart.Value := seGalaxieSystemeStart.Value;
                   seSondageSystemEnd.Value   := seGalaxieSystemeEnd.Value;

                   // TODO: Permettre que cela soit configurable
                   seSondageDureePourEtrePrisEnCompte.Value := 60 * 60 *  4;
                   seSondageIgnoreDelayLastSondage.Value    := 60 * 60 *  2;
                   
                end else
                   chkSonderEnsuiteLesInactifs.Checked := false;


                x := s.GetRequestPOST(TPL_VAR_ONPOST_PLANET_INDEX);
                iTmp := StrToIntDef(x, -1);
                if (iTmp < 0) or (iTmp >= cbGalaxieScanPlanete.Items.Count) then begin
                   MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
                   exit;
                end;
                cbGalaxieScanPlanete.ItemIndex := iTmp;


                PostMessage(Handle, WM_OPERATION_CODE, TUNNEL_OPCODE_SPIDER_SCAN, 0);
                MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 1);


             end else begin
                // ne peut pas faire d'action
                MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
             end;


          end else begin
             // pas loggé
             MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
          end;


       end else begin
          // profil invalide
          MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
       end;
       

    end else if SameText(operation, TUNNEL_ROBOT_POSTVAL_OPERATION_STATS_RECOLTE) then begin
       if FCurrentPlayer.Conf.IsValidProfil then begin
          // profil valide, mais es-ce que le robot est loggé ?
          if FCurrentPlayer.IsLoggedAndCanDoSomething and cmdSpiderStatsScan.Enabled then begin
             PostMessage(Handle, WM_OPERATION_CODE, TUNNEL_OPCODE_STATS_RECOLTE, 0);
             MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 1);

          end else begin
             MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
          end;

       end else begin
          // profil invalide
          MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
       end;

       
    end else if SameText(operation, TUNNEL_ROBOT_POSTVAL_OPERATION_SPIDER_LOGIN) then begin
       if FCurrentPlayer.Conf.IsValidProfil then begin
          // profil valide, on essaye de se logger
          if menSpiderLogin.Enabled then begin
             PostMessage(Handle, WM_OPERATION_CODE, TUNNEL_OPCODE_SPIDER_DO_LOGIN, 0);
             MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 1);

          end else begin
             MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
          end;

       end else begin
          // profil invalide
          MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
       end;


    end else if SameText(operation, TUNNEL_ROBOT_POSTVAL_OPERATION_ATTACK) then begin
       // on attack une planète
       // et on doit être rediriger vers la page d'envoi de flotte
       // sur cette page, le robot s'occupe d'auto remplir les formulaires
       x := s.GetRequestGET(TUNNEL_ROBOT_POSTVAL_ATTACK_CIBLE);

       if x <> '' then begin
          cPlanet := mpcExtractPlanetLocation(x);

          // la galaxie doit être égale à celle actuellement charger
          if (cPlanet.Galaxie = FBase2DonneesRapports.Galaxie) then begin

             if (cPlanet.SystemSolaire > 0) and (cPlanet.Position > 0) then begin
                // valide
                // trouve le rapport associé
                FCurrentSocketTunnelRapport := FBase2DonneesRapports.Get_Pointeur(cPlanet);

                if FCurrentSocketTunnelRapport <> nil then begin
                   MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 1);
                   
                end else begin
                   MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
                end;

             end else begin
                MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
             end;

          end else begin
             MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
          end;

       end else begin
          // echec
          MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
       end;


    end else if SameText(operation, TUNNEL_ROBOT_POSTVAL_OPERATION_SONDAGE_CLEAR) then begin
       FCurrentPlayer.SondagePlanetesList.Clear;
       MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 1);

    end else if SameText(operation, TUNNEL_ROBOT_POSTVAL_OPERATION_SONDAGE_STOP) then begin



        if cmdSondageStop.Enabled and FCurrentPlayer.Conf.IsValidProfil then begin
           MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 1);

           cmdSondageStopClick(nil);

        end else begin
           MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
        end;


    end else if SameText(operation, TUNNEL_ROBOT_POSTVAL_OPERATION_SONDAGE_START) then begin

       if FCurrentPlayer.Conf.IsValidProfil then begin
          // profil valide, mais es-ce que le robot est loggé ?
          if FCurrentPlayer.IsLoggedAndCanDoSomething and cmdSondageStart.Enabled then begin
             // le click déclenche un timer
             // l'opération est non bloquante, pas la peine d'utiliser PostMessage
             cmdSondageStartClick(nil);

             MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 1);

             
          end else begin
             MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
          end;

       end else begin
          MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
       end;


       
    end else if SameText(operation, TUNNEL_ROBOT_POSTVAL_OPERATION_LIRE_MSG) then begin
       if FCurrentPlayer.Conf.IsValidProfil then begin
          // profil valide, mais es-ce que le robot est loggé ?
          if cmdMessageListGet.Enabled then begin
              PostMessage(Handle, WM_OPERATION_CODE, TUNNEL_OPCODE_LIRE_MSG, 0);
              MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 1);

          end else begin
              MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
          end;

       end else begin
          // profil invalide
          MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
       end;

    end;


end;


procedure TfrmRapportHistorique.TunnelROBOT_TemplateSetPlaneteList(s: TTunnelHttpConnection; t: TTemplatePage);
var i: integer;
    PlaneteName, PlaneteCoord: string;
    xPos: integer;
begin

(*
       // liste de planètes
       t.ConditionSet(TPL_COND_PLANETE_COUNT, FCurrentPlayer.Conf.PlanetesList.Count);
       if FCurrentPlayer.Conf.PlanetesList.Count > 0 then begin
          t.BoucleStart(TPL_LOOP_PLANETELIST);


          for i := 0 to FCurrentPlayer.Conf.PlanetesList.Count - 1 do begin
             if i <> 0 then
                t.BoucleStart('');

             PlaneteName := FCurrentPlayer.Conf.PlanetesList.Strings[i];

             xPos := LastDelimiter('-', PlaneteName);
             if xPos > 0 then begin
                PlaneteCoord := trim(copy(PlaneteName, xPos + 1, maxint));
                System.Delete(PlaneteName, xPos, maxint);
                PlaneteName := trim(PlaneteName);

             end else begin
                PlaneteCoord := '0:0:0';
             end;

             t.BoucleSetVar(TPL_VARLOOP_PLANETENAME, PlaneteName);
             t.BoucleSetVar(TPL_VARLOOP_PLANETECOORD, PlaneteCoord);
             t.BoucleSetVar(TPL_VARLOOP_ID, i);

             t.BoucleEnd;
          end;

       end;
            *)


       // liste de planètes
       t.ConditionSet(TPL_COND_PLANETE_COUNT, cbGalaxieScanPlanete.Items.Count);
       if cbGalaxieScanPlanete.Items.Count > 0 then begin
          t.BoucleStart(TPL_LOOP_PLANETELIST);


          for i := 0 to cbGalaxieScanPlanete.Items.Count - 1 do begin
             if i <> 0 then
                t.BoucleStart('');

             PlaneteName := cbGalaxieScanPlanete.Items.Strings[i];

             xPos := LastDelimiter('-', PlaneteName);
             if xPos > 0 then begin
                PlaneteCoord := trim(copy(PlaneteName, xPos + 1, maxint));
                System.Delete(PlaneteName, xPos, maxint);
                PlaneteName := trim(PlaneteName);

             end else begin
                PlaneteCoord := '0:0:0';
             end;

             t.BoucleSetVar(TPL_VARLOOP_PLANETENAME, PlaneteName);
             t.BoucleSetVar(TPL_VARLOOP_PLANETECOORD, PlaneteCoord);
             t.BoucleSetVar(TPL_VARLOOP_ID, i);

             t.ConditionSet(TPL_COND_PLANETE_ISSELECTED, cbGalaxieScanPlanete.ItemIndex = i);

             t.BoucleEnd;
          end;

       end;



end;


procedure TfrmRapportHistorique.TunnelROBOT_TemplateSetGlobalValue(s: TTunnelHttpConnection; t: TTemplatePage);
var pe: PPlayerStats;
begin
      // options globales
       t.ConditionSet(TPL_COND_ROBOT_PROFIL_IS_VALID, 1);

       t.SetVar(TPL_VAR_ROBOT_PROFIL_NICKNAME, FCurrentPlayer.Conf.Pseudo);
       t.SetVar(TPL_VAR_ROBOT_PROFIL_UNIVERS , FCurrentPlayer.Conf.Univers);



       if FCurrentPlayer <> nil then begin
          pe := FCurrentPlayer.StatsPlayer.Get_Pointeur(FCurrentPlayer.Conf.Pseudo);

          if pe <> nil then begin
             t.ConditionSet(TPL_COND_ROBOT_PROFIL_POINTS_GLOBAL, pe.Points);
             t.SetVar(TPL_VAR_ROBOT_PROFIL_POINTS_GLOBAL, sfcFormatStrToMilliersPX(pe.Points));
          end else begin
             t.ConditionSet(TPL_COND_ROBOT_PROFIL_POINTS_GLOBAL, -1);
             t.SetVar(TPL_VAR_ROBOT_PROFIL_POINTS_GLOBAL, '');
          end;

          pe := FCurrentPlayer.StatsPlayerFlottes.Get_Pointeur(FCurrentPlayer.Conf.Pseudo);
          if pe <> nil then begin
             t.ConditionSet(TPL_COND_ROBOT_PROFIL_POINTS_FLOTTES, pe.Points);
             t.SetVar(TPL_VAR_ROBOT_PROFIL_POINTS_FLOTTES, sfcFormatStrToMilliersPX(pe.Points));
          end else begin
             t.ConditionSet(TPL_COND_ROBOT_PROFIL_POINTS_FLOTTES, -1);
             t.SetVar(TPL_VAR_ROBOT_PROFIL_POINTS_FLOTTES, '');
          end;


       end else begin
             t.ConditionSet(TPL_COND_ROBOT_PROFIL_POINTS_GLOBAL, -2);
             t.SetVar(TPL_VAR_ROBOT_PROFIL_POINTS_GLOBAL, '');

             t.ConditionSet(TPL_COND_ROBOT_PROFIL_POINTS_FLOTTES, -2);
             t.SetVar(TPL_VAR_ROBOT_PROFIL_POINTS_FLOTTES, '');
       end;



       // proxy informations
       t.ConditionSet(TPL_COND_ROBOT_PROFIL_PROXY_ACTIVE, FCurrentPlayer.Conf.ProxyActive);
       t.ConditionSet(TPL_COND_ROBOT_PROFIL_PROXY_TYPE  , FCurrentPlayer.Conf.ProxyType);
       t.ConditionSet(TPL_COND_ROBOT_PROFIL_PROXY_IDENT_ACTIVE  , FCurrentPlayer.Conf.ProxyIdentActive);

       t.SetVar(TPL_VAR_ROBOT_PROFIL_ProxyHostname, FCurrentPlayer.Conf.ProxyHostname);
       t.SetVar(TPL_VAR_ROBOT_PROFIL_ProxyPort , FCurrentPlayer.Conf.ProxyPort);
       t.SetVar(TPL_VAR_ROBOT_PROFIL_ProxyUsername , FCurrentPlayer.Conf.ProxyUsername);


       // agent émulé
       t.ConditionSet(TPL_COND_ROBOT_PROFIL_NAV_GZIP  , FCurrentPlayer.Conf.NavGZipEncoding);

       t.SetVar(TPL_VAR_ROBOT_PROFIL_NavAgent, FCurrentPlayer.Conf.NavAgent);
       t.SetVar(TPL_VAR_ROBOT_PROFIL_NavAcceptLanguage , FCurrentPlayer.Conf.NavAcceptLanguage);
       t.SetVar(TPL_VAR_ROBOT_PROFIL_NavAccept , FCurrentPlayer.Conf.NavAccept);




       // Onglet profil
       t.SetVar(TPL_VAR_ROBOT_PROFIL_CURR_GALAXIE_SPINEDIT, seDBGalaxie.Value);

       t.SetVar(TPL_VAR_ROBOT_PROFIL_STATS_RAPPORTS_FILENAME , lblProfilFichierRapportDB.Caption);
       t.SetVar(TPL_VAR_ROBOT_PROFIL_STATS_RAPPORTS_NB       , lblNbPlanetesLoaded.Caption);

       t.SetVar(TPL_VAR_ROBOT_PROFIL_STATS_GALAXY_FILENAME , lblProfilFichierGalaxyDB.Caption);
       t.SetVar(TPL_VAR_ROBOT_PROFIL_STATS_GALAXY_NB , lblNbPlaneteLoadedGalaxy.Caption);


       t.ConditionSet(TPL_COND_ROBOT_PROFIL_GALAXIE_LOADED, FInfosBaseDeDonneCharge);
       if FInfosBaseDeDonneCharge then begin
          t.SetVar(TPL_VAR_ROBOT_PROFIL_CURR_GALAXIE_LOADED , FBase2DonneesRapports.Galaxie);

       end else begin
          t.SetVar(TPL_VAR_ROBOT_PROFIL_CURR_GALAXIE_LOADED , -1);
       end;


       // Le spider
       t.SetVar(TPL_VAR_SCAN_SYSYEM_START , seGalaxieSystemeStart.Value);
       t.SetVar(TPL_VAR_SCAN_SYSTEM_END   , seGalaxieSystemeEnd.Value);
       t.SetVar(TPL_VAR_SCAN_DUREE_SKIP   , seSpiderGalaxieDureeRecent.Value);


       // Les sondages
       t.SetVar(TPL_VAR_SONDAGE_SYSYEM_START , seSondageSystemStart.Value);
       t.SetVar(TPL_VAR_SONDAGE_SYSTEM_END   , seSondageSystemEnd.Value);
       t.SetVar(TPL_VAR_SONDAGE_DUREE_KEEP   , seSondageDureePourEtrePrisEnCompte.Value);
       t.SetVar(TPL_VAR_SONDAGE_DUREE_RECENT , seSondageIgnoreDelayLastSondage.Value);

       t.SetVar(TPL_VAR_SONDAGE_MAX_DEFENSE  , seSondageMaxScoreDef.Value);
       t.ConditionSet(TPL_COND_SONDAGE_MAX_DEFENSE, chkSondageMaxDefScore.Checked);

       t.SetVar(TPL_VAR_SONDAGE_MIN_PT       , seSondageMinPT.Value);
       t.ConditionSet(TPL_COND_SONDAGE_MIN_PT, chkSondageMinPT.Checked);


       t.ConditionSet(TPL_COND_SONDAGE_IGNORE_ATTAQUER_2H , chkSondageDontAddDejaAttack2h.Checked);
       t.ConditionSet(TPL_COND_SONDAGE_IGNORE_ATTAQUER_12H, chkSondageDontAddDejaAttack12h.Checked);
       t.ConditionSet(TPL_COND_SONDAGE_IGNORE_ATTAQUER_24H, chkSondageDontAddDejaAttack24h.Checked);


       t.ConditionSet(TPL_COND_SONDAGE_PARPOINTS_COND_OR                   , optAttaqueOR.Checked);
       t.ConditionSet(TPL_COND_SONDAGE_PARPOINTS_GLOBAL_INCLURE_NON_CLASSES, chkSondagePointGlobalNonClasse.Checked);
       t.ConditionSet(TPL_COND_SONDAGE_PARPOINTS_FLOTTE_INCLURE_NON_CLASSES, chkSondagePointFlottesNonClasse.Checked);
       t.ConditionSet(TPL_COND_SONDAGE_PARPOINTS_EXCLURE_INACTIFS, chkSondageStatsExclureInactif.Checked);

       t.SetVar(TPL_VAR_SONDAGE_PARPOINTS_MAX_GLOBALES , seSondageStatsLimitGlobales.Value);
       t.SetVar(TPL_VAR_SONDAGE_PARPOINTS_MAX_FLOTTES  , seSondageStatsLimitFlottes.Value);

       t.ConditionSet(TPL_COND_SONDAGE_EN_COURS, cmdSondageStop.Enabled);




       // le robot s'est t-il déjà loggé une fois ?
       t.SetVar(TPL_VAR_PLAYER_GAME_SESSION_ID , FCurrentPlayer.iSessionId);
       t.SetVar(TPL_VAR_PLAYER_URL_DIR         , FCurrentPlayer.iURLGameDir);

       if FCurrentPlayer.iSessionId <> '' then begin
          t.ConditionSet(TPL_COND_ROBOT_DEJA_LOGGER_UNEFOIS  , 1);
       end else begin
          t.ConditionSet(TPL_COND_ROBOT_DEJA_LOGGER_UNEFOIS  , 0);
       end;

       t.ConditionSet(TPL_COND_ROBOT_DOIT_SE_RELOGGER  , FCurrentPlayer.iMustRelogin);








end;


procedure TfrmRapportHistorique.TunnelTraitement_ROBOT(s: TTunnelHttpConnection; Params: string);
var i, j, k: integer;
begin

    Lock;


    if chkTunnelInterdireAccesAdmin.Checked then begin
       // access refusé
       TunnelSendFile(s, TUNNEL_GAME_FILE_PAGE_REFUSEE);
       Unlock;
       exit;
    end;




    if FCurrentPlayer.Conf.IsValidProfil then begin
       TunnelROBOT_TemplateSetGlobalValue(s, MotorTemplate);



    end else begin
       // options globales
       MotorTemplate.ConditionSet(TPL_COND_ROBOT_PROFIL_IS_VALID, 0);

       MotorTemplate.SetVar(TPL_VAR_ROBOT_PROFIL_NICKNAME, '');
       MotorTemplate.SetVar(TPL_VAR_ROBOT_PROFIL_UNIVERS , '');


       // proxy informations
       MotorTemplate.ConditionSet(TPL_COND_ROBOT_PROFIL_PROXY_ACTIVE, 0);
       MotorTemplate.ConditionSet(TPL_COND_ROBOT_PROFIL_PROXY_TYPE  , 0);
       MotorTemplate.ConditionSet(TPL_COND_ROBOT_PROFIL_PROXY_IDENT_ACTIVE  , 0);

       MotorTemplate.SetVar(TPL_VAR_ROBOT_PROFIL_ProxyHostname, '');
       MotorTemplate.SetVar(TPL_VAR_ROBOT_PROFIL_ProxyPort , '');
       MotorTemplate.SetVar(TPL_VAR_ROBOT_PROFIL_ProxyUsername , '');


       // agent émulé
       MotorTemplate.ConditionSet(TPL_COND_ROBOT_PROFIL_NAV_GZIP  , 0);

       MotorTemplate.SetVar(TPL_VAR_ROBOT_PROFIL_NavAgent, '');
       MotorTemplate.SetVar(TPL_VAR_ROBOT_PROFIL_NavAcceptLanguage , '');
       MotorTemplate.SetVar(TPL_VAR_ROBOT_PROFIL_NavAccept , '');
    end;


    if (s.GetRequestPOST(TUNNEL_ROBOT_POST_OPERATION) <> '') or (s.GetRequestGET(TUNNEL_ROBOT_POST_OPERATION) <> '') then begin
       TunnelTraitement_ROBOT_Operation(s, MotorTemplate);
    end else begin
       MotorTemplate.ConditionSet(TPL_COND_ISFROMPOST_REQ, 0);
    end;


    

    if (Params = '') or (SameText(Params, 'index')) or (SameText(Params, 'index.htm')) then begin
        // page d'index
        MotorTemplate.LoadFromFile(TunnelGetFullFile(TUNNEL_ROBOT_FILE_INDEX));
        TunnelROBOT_TemplateSetPlaneteList(s, MotorTemplate);
        
        MotorTemplate.ProceedFinal;


        if MotorTemplate.DocumentOut = '' then
           s.MakeErreur(404)
        else
           s.SendPageWeb(MotorTemplate.DocumentOut);

        MotorTemplate.Clear;


    end else if SameText(Params, 'selection_profil') then begin

        MotorTemplate.LoadFromFile(TunnelGetFullFile(TUNNEL_ROBOT_FILE_PROFIL_SELECTION));

        if FTunnelProfilList = nil then begin
           RefreshProfilList;
        end;

        if FTunnelProfilList.Count > 0 then begin
           MotorTemplate.BoucleStart(TPL_LOOP_PROFILW_LIST);

           for i := 0 to FTunnelProfilList.Count - 1 do begin
              MotorTemplate.BoucleSetVar(TPL_VARLOOP_PROFIL_NAME, FTunnelProfilList.Strings[i]);
              MotorTemplate.BoucleSetVar(TPL_VARLOOP_PROFIL_ID  , IntToStr(i));

              MotorTemplate.BoucleEnd;
           end;

        end;

        MotorTemplate.ProceedFinal;

        if MotorTemplate.DocumentOut = '' then
           s.MakeErreur(404)
        else
           s.SendPageWeb(MotorTemplate.DocumentOut);

        MotorTemplate.Clear;

    end else if SameText(Params, 'editprofile') then begin



    end else if SameText(Params, 'recent_view') then begin
        MotorTemplate.LoadFromFile(TunnelGetFullFile(TUNNEL_ROBOT_FILE_PROFIL_RAPPORT_RECENT_VIEW));


        UpdateAllSpecForSocket(MotorTemplate, FBaseRecent);

        MotorTemplate.ProceedFinal;
        if MotorTemplate.DocumentOut = '' then
           s.MakeErreur(404)
        else
           s.SendPageWeb(MotorTemplate.DocumentOut);

        MotorTemplate.Clear;



    end else if SameText(Params, 'sondage_view') then begin
        MotorTemplate.LoadFromFile(TunnelGetFullFile(TUNNEL_ROBOT_FILE_PROFIL_SONDAGE_VIEW));

        UpdateSondagesForSocket(MotorTemplate);
        

        MotorTemplate.ProceedFinal;
        if MotorTemplate.DocumentOut = '' then
           s.MakeErreur(404)
        else
           s.SendPageWeb(MotorTemplate.DocumentOut);

        MotorTemplate.Clear;




    end else if SameText(Params, 'sondage_stop') then begin

        MotorTemplate.LoadFromFile(TunnelGetFullFile(TUNNEL_ROBOT_FILE_PROFIL_SONDAGE_STOP));



        if cmdSondageStop.Enabled and FCurrentPlayer.Conf.IsValidProfil then begin
           MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 1);

           cmdSondageStopClick(nil);

        end else begin
           MotorTemplate.ConditionSet(TPL_COND_OPERATION_STATE, 0);
        end;


        MotorTemplate.ProceedFinal;
        if MotorTemplate.DocumentOut = '' then
           s.MakeErreur(404)
        else
           s.SendPageWeb(MotorTemplate.DocumentOut);

        MotorTemplate.Clear;


    end else if SameText(Params, 'status_clear') then begin

        txtDebug1.Lines.Clear;
        MotorTemplate.LoadFromFile(TunnelGetFullFile(TUNNEL_ROBOT_FILE_PROFIL_STATUS_CLEAR));

        MotorTemplate.SetVar(TPL_VAR_STATUS_TOTAL_MSG , txtDebug1.Lines.Count);

        MotorTemplate.ProceedFinal;

        if MotorTemplate.DocumentOut = '' then
           s.MakeErreur(404)
        else
           s.SendPageWeb(MotorTemplate.DocumentOut);

        MotorTemplate.Clear;

    
    end else if SameText(Params, 'status') then begin
        // visualisation du status
        MotorTemplate.LoadFromFile(TunnelGetFullFile(TUNNEL_ROBOT_FILE_PROFIL_STATUS));


        if txtDebug1.Lines.Count < 40 then begin
           j := 0;
        end else begin
           j := txtDebug1.Lines.Count - 40;
        end;

        MotorTemplate.ConditionSet(TPL_COND_STATUS_TOTAL_MSG, txtDebug1.Lines.Count);
        MotorTemplate.SetVar(TPL_VAR_STATUS_TOTAL_MSG , txtDebug1.Lines.Count);

        MotorTemplate.BoucleStart(TPL_LOOP_STATUS_VIEW);
        k := 1;
        for i := j to txtDebug1.Lines.Count - 1 do begin
           MotorTemplate.BoucleSetVar(TPL_VARLOOP_LIGNE        , txtDebug1.Lines.Strings[i]);
           MotorTemplate.BoucleSetVar(TPL_VARLOOP_IDROBOTLIGNE , IntToStr(i));
           MotorTemplate.BoucleSetVar(TPL_VARLOOP_IDLIGNE      , IntToStr(k));

           Inc(k);

           MotorTemplate.BoucleEnd;
        end;

        MotorTemplate.ProceedFinal;

        if MotorTemplate.DocumentOut = '' then
           s.MakeErreur(404)
        else
           s.SendPageWeb(MotorTemplate.DocumentOut);

        MotorTemplate.Clear;


    end else begin
        i := pos('?', Params);
        if i > 0 then begin
           System.Delete(Params, i, maxint);
        end;
        MotorTemplate.LoadFromFile(TunnelGetFullFile('robot/' + Params));
        TunnelROBOT_TemplateSetPlaneteList(s, MotorTemplate);

        MotorTemplate.ProceedFinal;
        if MotorTemplate.DocumentOut = '' then
           s.MakeErreur(404)
        else
           s.SendPageWeb(MotorTemplate.DocumentOut);

        MotorTemplate.Clear;
    end;


    Unlock;


end;


procedure TfrmRapportHistorique.TunnelTraitement_RELAY(s: TTunnelHttpConnection; Params: string);
var user, pass: string;
    tidc: TTunnelSessionId;
    bState: boolean;
begin

    if SameText(Params, 'login') then begin
        //s.ClientThread.Display(s.RequestPostedData);

        
        // pas de cache
        s.MakeNoCache;

        user := s.GetRequestPOST(TUNNEL_POST_NAME_USERNAME);
        pass := s.GetRequestPOST(TUNNEL_POST_NAME_PASSWORD);



        bState := false;


        if (user = txtTunnelRootUser.Text) and (length(pass) > 3) then begin
           // root

           if pass = txtTunnelRootPass.Text then begin
              // auth valid
              tidc.sessionid   := md5StringX(IntToStr(DateTimeToUnix(Now)) + pass + s.GetPeerAddr + user);
              tidc.Utilisateur := user;
              tidc.ip          := s.GetPeerAddr;
              tidc.Access      := 9000;
              tidc.DateExp     := DatetimeToUnix(Now) + 18000;

              s.SetCookie(TUNNEL_COOKIE_AUTH_SESSION_ID, tidc.sessionid, 0, '/');

              FTunnelSessionId.Add(tidc);


              bState := true;
           end;
        end;



        if bState then begin
           MotorTemplate.LoadFromFile(TunnelGetFullFile(TUNNEL_RELAY_FILE_LOGIN_SUCCESS));
           MotorTemplate.ProceedFinal;

        end else begin
           MotorTemplate.LoadFromFile(TunnelGetFullFile(TUNNEL_RELAY_FILE_LOGIN_PAGE));
           MotorTemplate.ConditionSet(TPL_COND_LOGINPAGE_PASSWORD_INVALID, 1);
           MotorTemplate.ProceedFinal;

        end;

        if MotorTemplate.DocumentOut = '' then
           s.MakeErreur(404)
        else
           s.SendPageWeb(MotorTemplate.DocumentOut);

        MotorTemplate.Clear;


    end else if SameText(Params, 'selection') then begin
        TunnelSendFile(s, TUNNEL_RELAY_FILE_SELECTION_SERVICE);


    end else begin
        TunnelSendFile(s, TUNNEL_RELAY_FILE_SELECTION_SERVICE);

    end;

end;

procedure TfrmRapportHistorique.menActionDescendreClick(Sender: TObject);
begin
    if FCurrPlayerCurrPlanete = nil then exit;

    if FLastLigneSelectPlaneteScript < FCurrPlayerCurrPlanete.cActions.Count then begin
       FCurrPlayerCurrPlanete.cActions.Exchange(FLastLigneSelectPlaneteScript, FLastLigneSelectPlaneteScript - 1);

       // Met à jour l'affichage
       AfficheActionInGrid(sgElementsAction, FCurrPlayerCurrPlanete.cActions);
    end;

end;

function TfrmRapportHistorique.DoForumGetAccess: TBoardFonctionLoginResult;
label lEnd, lCaseSucess;
var authBoard: TBoardMotor;
    UpdateFile: TFichierUpdateParsing;
    socket: THttpCli;
    r: integer;
    i64: int64;
begin

          {$IFDEF AUTH_FILE_USE}
             // les VIP ont toujours accès au forum SANS passer par le serveur
             // d'identification
             goto lCaseSucess;
          {$ENDIF}




    Result := tbflUserError;
    if FDoForumGetAccessInThis then begin
       exit;
    end;

    if FForumGetAccessNbEchec > 5 then begin
       // trop de tentative échoué pour cette session
       exit;
    end;


    if (length(txtForumPassword.Text) < 5) or (length(txtForumUsername.Text) < 5) then begin
       // invalide
       exit;
    end;

    i64 := Crypto_AlgoIrreversible1_Codage(txtForumUsername.Text + txtForumPassword.Text);

    if i64  = FForumGetAccessDeniedForHash then begin
       // access refusé
       Result := tbflInvalidUserOrPass;
       exit;
    end;

    FDoForumGetAccessInThis := true;



    // Charge les données avancées
    FLocalSetting.LoadFromFile('', lsoIniCryptedData);

    // Vérifie si l'url du serveur d'identification est valide
    if FLocalSetting.IniURL_ForumCheckAccess = '' then begin

       // ce n'est pas le cas
       // on télécharge un fichier miroir valide
       UpdateFile := iwFindValidMirroirFileAndDLIt(FLocalSetting.ConfGet(CNT_LOCALSETTING_UpdateMirrorFileNextIdToStart), 3);

       if UpdateFile = nil then begin
          if FLocalSetting.ConfGet(CNT_LOCALSETTING_UpdateMirrorFileNextIdToStart) > 0 then begin
             // ok, on recommence du début
             FLocalSetting.ConfSet(CNT_LOCALSETTING_UpdateMirrorFileNextIdToStart, 0);

             UpdateFile := iwFindValidMirroirFileAndDLIt(0, 2);
          end;
       end;

       if UpdateFile = nil then begin
          Status(_('Board: Téléchargement échoué'));
          Result := tbflNoAuthURLFound;
          goto lEnd;
       end;

       // traite le fichier
       TraitementFichierUpdate(UpdateFile);

       // mémorise le fichier update pour le retélécharger en cas de besoin
       FLocalSetting.ConfSet(CNT_LOCALSETTING_UpdateMirrorFileNextIdToStart, UpdateFile.IdUpdateFile);

       // succés de l'opération
       UpdateFile.Free;
       UpdateFile := nil;

       // sauvegarde l'URL
       FLocalSetting.SaveToFile('', [lsoIniCryptedData]);

    end;


    if FLocalSetting.IniURL_ForumCheckAccess = '' then begin
       // toujours inacessible
       Status(_('Board: Téléchargement échec total'));
       Result := tbflNoAuthURLFound;
       goto lEnd;
    end;



    authBoard := TBoardMotor.Create;

    socket := authBoard.SocketWeb;
    ConfigForumSocket(socket);

    authBoard.DebugProc := Status;


    authBoard.LoginEmail := txtForumUsername.Text;
    authBoard.LoginPass  := txtForumPassword.Text;



    //r := authBoard.Login('http://127.0.0.1/ru/forum_crypt/login.php');
    r := authBoard.Login(FLocalSetting.IniURL_ForumCheckAccess);



    if r > 0 then begin
lCaseSucess:

       Result := tbflSuccess;

       FLocalSetting.ConfSet64(CNT_LOCALSETTING_DATEAutorisation_Forum, DatetimeToUnix(Now) + CNT_BOARD_VALIDITE_IDENT);

       //i64 := Crypto_AlgoIrreversible1_Codage(authBoard.LoginEmail + authBoard.LoginPass);
       FLocalSetting.ConfSet64(CNT_LOCALSETTING_KEYAutorisation_Forum, i64);




    end else begin

       FLocalSetting.ConfSet64(CNT_LOCALSETTING_KEYAutorisation_Forum , 0);
       FLocalSetting.ConfSet64(CNT_LOCALSETTING_DATEAutorisation_Forum, 0);

       if r = CNT_BOARD_SOCKET_ERROR then begin
          // excusable
          Status(_('Board socket error'));
          Result := tbflSocketError;


       end else if r = CNT_BOARD_CHALLENGE_NOT_FOUND then begin
          // clé de challenge non trouvé
          // cela signifie que l'utilisateur est invalide
          Status(_('Board error: Utilisateur ou mot de passe invalide'));
          FForumGetAccessDeniedForHash := i64;

          Inc(FForumGetAccessNbEchec);

       end else if r = CNT_BOARD_CLOSED then begin
          // la page de vérification n'est plus valide
          // on devrait télécharger à nouveau le fichier update...
          Status(_('Board error: Board closed (fermé)'));
          Result := tbflSocketError;

          i64 := FLocalSetting.ConfGet64(CNT_LOCALSETTING_UpdateFileLastDL);

          if (DatetimeToUnix(Now) - i64) > CNT_BOARD_UPDATE_FILE_PERIMED_IF_FAIL then begin
             // ok, on ferai mieux de télécharger à nouveau le fichier update
             // pour cela on réinitialise l'url
             FLocalSetting.IniURL_ForumCheckAccess := '';

             // et on sauvegarde
             FLocalSetting.SaveToFile('', [lsoIniCryptedData]);
          end;

          Inc(FForumGetAccessNbEchec);

       end else begin
          // sinon couple invalide (autre erreur ?)
          Status('Board error: ' + IntToStr(r));
          Result := tbflInvalidUserOrPass;
          FForumGetAccessDeniedForHash := i64;

          Inc(FForumGetAccessNbEchec);
       end;

    end;

    authBoard.Free;

lEnd:
    FLocalSetting.BurnSecu;
    FDoForumGetAccessInThis := false;

end;

function TfrmRapportHistorique.GetForumCanAccess: boolean;
var CurrDate: int64;
    iResult: TBoardFonctionLoginResult;
    iHash: int64;
begin


          {$IFDEF AUTH_FILE_USE}
             Result := true;
             exit;
          {$ENDIF}

          // en attendant de trouver un autre hébergeur pour la gestion des accès
          // on se connecte directement au vrai forum...
             Result := true;
             exit;



       Result   := false;
       CurrDate := DatetimeToUnix(Now);


       // on prévoit un délai de 24h
       if FLocalSetting.ConfGet64(CNT_LOCALSETTING_DATEAutorisation_Forum) < CurrDate  then begin
          // le délai à expiré
          // on doit obtenir à nouveau l'autorisation


          iResult := DoForumGetAccess;

          if iResult = tbflSuccess then begin
             Result := true;
          end;



       end else begin

          // vérifie si l'identification n'a pas changé
          iHash := Crypto_AlgoIrreversible1_Codage(txtForumUsername.Text + txtForumPassword.Text);

          if iHash <> FLocalSetting.ConfGet64(CNT_LOCALSETTING_KEYAutorisation_Forum) then begin
             // on doit refaire l'identification sur le site de gestion d'accès
             // ou bloque l'acccès tout simplement ?
             // la personne n'a pas à changer ses identifiants
             exit;
          end;


          if (FLocalSetting.ConfGet64(CNT_LOCALSETTING_DATEAutorisation_Forum) - CurrDate) < CNT_BOARD_RELOG_BEFORE_EXPIRATION then begin
             // le délai va expirer dans moins de 172800 secondes, on obtient à nouveau l'autorisation, mais
             // en mode non bloquant
             if NoT(FForumGetDelayedAccessDone) then begin
                FServiceDelayCmd := SERVICES_CMD_DO_GET_FORUM_AUTORIZATION;
                timServiceDelayCmd.Interval := 1500;
                FForumGetDelayedAccessDone := true;
             end;

          end;

          Result := true;
       end;



end;


procedure umhttpGETorPOST_DefDefautSock(var sckHttp: THttpCli);
begin
    // Définit le serveur Socks (aucun)
    sckHttp.SocksServer         := '';
    sckHttp.SocksPort           := '1080';
    sckHttp.SocksAuthentication := socksNoAuthentication;


    // ne suit pas les relocation
    //sckHttp.FollowRelocation := false;


    // Définit le serveur proxy http (aucun)
    sckHttp.Proxy      := '';
    sckHttp.ProxyPort  := '80';
end;


procedure TfrmRapportHistorique.ConfigForumSocket(var Socket: THttpCli);
begin
       umhttpGETorPOST_DefDefautSock(Socket);

       // fucking relocation
       // on est seulement un proxy
       Socket.FollowRelocation  := false;

       Socket.Cookie := '';
end;


procedure TfrmRapportHistorique.TunnelTraitement_FORUM(s: TTunnelHttpConnection; Params: string);
var sPageWeb: string;
    RealURL : string;
    RelocURL: string;

    FichierRessource: string;
    FichierStream   : TFileStream;

    bIsTemplateFile: boolean;

    sComp, sComp2: string[64];
    
begin

       // pas de forum
       //s.SendFile(TunnelGetFullFile(TUNNEL_FORUM_FILE_NOFORUMFOUND), true);
       //exit;


       if (length(txtForumUsername.Text) < 3) or (length(txtForumPassword.Text) < 3) then begin
          // accès refusé
          s.SendFile(TunnelGetFullFile(TUNNEL_FORUM_FILE_NOT_CONFIG), true);
          exit;

       end else if  (length(FForumRelay.URL) < 3) or (length(FForumRelay.URLForModif) < 3) then begin
          // forum non trouvé

          // vérifie si il est autorisé
          if GetForumCanAccess then begin

             if FForumRelay.URL = '' then begin
                // charge l'url
                tsiExtractForumURL(FForumRelay);
             end;

             if  (length(FForumRelay.URL) < 3) or (length(FForumRelay.URLForModif) < 3) then begin
                // erreur...
                s.SendFile(TunnelGetFullFile(TUNNEL_FORUM_FILE_NOFORUMFOUND), true);
                exit;
             end;

          end else begin
             s.SendFile(TunnelGetFullFile(TUNNEL_FORUM_FILE_ACCESS_REFUSE), true);
             exit;

          end;
     //  end else if length(FForumRelay.DataForLogin) < 3 then begin
     //     FForumRelay.DataForLogin := '';
       end;



       





       sComp  := copy(Params,1, 10);
       sComp2 := copy(Params,1, 7);

       if SameText(sComp, 'templates/') or SameText(sComp2, 'images/')  then begin
          // fichier template
          // peut-être présent sur le pc
          bIsTemplateFile := true;

          FichierRessource := TunnelGetFullFile('forum/' + Params);

          if FileExists(FichierRessource) then begin
             RelocURL := tlgCalculETag(FichierRessource);


             if s.RequestIfNoneMatch <> '' then begin
                if s.RequestIfNoneMatch = RelocURL then begin
                   s.MakeNonModified;
                   exit;
                end;

             end;

             if RelocURL <> '' then begin
                s.AddHeaderLigne('ETag: "' + RelocURL + '"');
             end;


             //StatusSockets('Ressource locale: ' + FichierRessource);
             try
                s.SendFile(FichierRessource, true);
             finally
                // rien à faire
             end;
             exit;

          end else begin
             ForceDirectories(ExtractFileDir(FichierRessource));
             //StatusSockets('Ressource: ' + FichierRessource);
          end;


       end else begin
          bIsTemplateFile := false;
       end;

       //StatusSockets('Forum: ' + Params);


       if s.SocketRelay = nil then begin
          s.SocketRelay := THttpCli.Create(s);
       end;

       ConfigForumSocket(s.SocketRelay);

       // recopie les informations du navigateur de l'utilisateur
       s.SocketRelay.Accept    := s.RequestAccept;
       s.SocketRelay.Agent     := s.RequestUserAgent + ' X' + CNT_CURR_VERSION;
       s.SocketRelay.Reference := s.RequestReferer;


       // fucking relocation
       // on est seulement un proxy
       s.SocketRelay.FollowRelocation  := false;

       s.SocketRelay.Cookie := FForumCookies.GetCookieData;
      // StatusSockets('Cookies envoyés: ' + s.SocketRelay.Cookie);


//       s.SocketRelay.AuthorizationRequest.Add('Authorization: Basic ' + iaEncode64URL(txtForumUsername.Text + ':' + txtForumPassword.Text) + '==');

       s.SocketRelay.Username := txtForumUsername.Text;
       s.SocketRelay.Password := txtForumPassword.Text;
       s.SocketRelay.AuthBasicState := basicMsg1;
       s.SocketRelay.BasicAuthType  := basicAuthNormal;


  //     s.SocketRelay.AuthorizationSend := true;

       RealURL := FForumRelay.URL + Params;
       sPageWeb := FCurrentPlayer.myGETorPOST_InTamponX(RealURL, s.RequestPostedData, s.SocketRelay);


       FillChar(RealURL[1], length(RealURL), 0);
       RealURL := '';

       FForumCookies.ParseHeader(s.SocketRelay.RcvdHeader);

       //StatusSockets('Header reçu:');
       //StatusSockets(s.SocketRelay.RcvdHeader.Text);


       RelocURL := tlgExtractLocation(s.SocketRelay.RcvdHeader);

       if RelocURL <> '' then begin
          // THttpCli met toujours les liens en mode URL complète
          // on doit aller chercher la location d'origine dans l'header
          if pos('http', RelocURL) = 1 then begin
             // on refuse la relocation
             // car on doit rester sur le serveur local

             if pos(lowercase(FForumRelay.URL), lowercase(RelocURL)) > 0 then begin
                RelocURL := sfcRemplace(RelocURL, FForumRelay.URLForModif, '/forum');


             end else begin
                // une relocation ailleurs ?
                // à l'extérieur du site ?
                // bizarre, on interdit
                s.MakeErreur(404);
                exit;
             end;

          end else begin

             if pos(FForumRelay.URLDirOnly, RelocURL) = 1 then begin
                // relocation à partir du dossier root
                RelocURL := sfcRemplace(RelocURL, FForumRelay.URLDirOnly, '/forum/');

             end;
          end;

          s.AddHeaderLigne('Location: ' + RelocURL);
       end;

       if s.SocketRelay.StatusCode < 100 then begin
          // erreur...
          StatusSockets('Erreur: ' + Params);
          s.MakeErreur(404);
          exit;
       end;

       if (s.SocketRelay.StatusCode = 403) or (s.SocketRelay.StatusCode = 401) then begin
          // accès refusé
          s.SendFile(TunnelGetFullFile(TUNNEL_FORUM_FILE_ACCESS_REFUSE), true);

          // réinitialise le mot de passe pour forcer la mise à jour des informations
          txtForumPassword.Text := '';

          // réinitialise l'url
          FForumRelay.URL := '';
          exit;
       end;

       s.ReponseContentType := s.SocketRelay.ContentType;

       if SameText(copy(s.ReponseContentType, 1, 5), 'text/') then begin
          // on remplace les données
          // supprime le "http://domaine" de la page web
          // il restera donc le /dir/file.x ce qui fonctionne
          // ATTENTION: risque de problème pour les fichiers css
          sPageWeb := sfcRemplace(sPageWeb, FForumRelay.URLForModif, '/forum');
          sPageWeb := sfcRemplace(sPageWeb, FForumRelay.URLDirOnly, '/forum/');


       end;



       if bIsTemplateFile  and (length(sPageWeb) > 10) then begin
          // le sauvegarde sur le pc
          try
            FichierStream   := TFileStream.Create(FichierRessource, fmCreate);
          except
            FichierStream := nil;
          end;

          if FichierStream <> nil then begin
             try
                FichierStream.Write(sPageWeb[1], length(sPageWeb));
             finally
                FichierStream.Free;
                FichierStream := nil;
             end;

          end else begin
             // echec de sauvegarde de la ressource

          end;

          // calcul l'ETag
          RelocURL := tlgCalculETag(FichierRessource);
          if RelocURL <> '' then begin
             s.AddHeaderLigne('ETag: "' + RelocURL + '"');
          end;

       end;



       s.SendPageWeb(sPageWeb, s.SocketRelay.StatusCode);
end;


function TfrmRapportHistorique.TunnelGetMoreDataForTunnel_Apercu(sPageWeb: string): string;
var
    xParsingApercu: TParsingAppercu;
begin
    Result := '';

    exit;
    
    xParsingApercu := TParsingAppercu.Create(nil);


    if xParsingApercu.ParseBuffer(sPageWeb) then begin

       // TUNNEL_GAMEMISC_APERCU
       MotorTemplate.LoadFromFile(TunnelGetFullFile(TUNNEL_GAMEMISC_APERCU));

       MotorTemplate.ProceedFinal;

    end;


    xParsingApercu.Free;
end;


procedure WriteInThisFile(Fichier: string; Buffer: string);
var F: TFileStream;
begin


    if length(Buffer) < 1 then begin
       exit;
    end;
    
    try
       F := TFileStream.Create(Fichier, fmCreate);
    except
       F := nil;
    end;

    if F = nil then begin
       exit;
    end;

    F.Write(Buffer[1], length(Buffer));

    F.Free;

end;




procedure TfrmRapportHistorique.TunnelTraitement_GAME(s: TTunnelHttpConnection; Params: string);
label lCacheExist;
var OgameURL, OgameURLlw, oReferer: string;
    sPageWeb: string;
    subDir, xPageTemp, xBuff, xBuff2, xBuffGT: string;
    xPos: integer;
    iPageType: integer;
    iMiscActionOnThePage: integer;
    xParser: TParsingFlotte2_ChoixDestination;

    sCachedFile : string;
    bCanBeCached: boolean;
    iDiff: int64;
begin


    iMiscActionOnThePage := 0;
    bCanBeCached := false;
    
    
    if Params = '' then begin
       // on définit les frames
       if length(FCurrentPlayer.iURLGameDir) < 10 then begin
          TunnelSendFile(s, TUNNEL_GAME_FILE_NOT_LOGGED);

       end else begin
          //TunnelSendFile(s, TUNNEL_GAME_FILE_FRAMESET);
          
          MotorTemplate.LoadFromFile(TunnelGetFullFile(TUNNEL_GAME_FILE_FRAMESET));


          TunnelROBOT_TemplateSetGlobalValue(s, MotorTemplate);

          MotorTemplate.ProceedFinal;

          if MotorTemplate.DocumentOut <> '' then begin
             s.SendPageWeb(MotorTemplate.DocumentOut);
          end else begin
             s.MakeErreur(404);
          end;

          MotorTemplate.Clear;

       end;



    end else begin
       //FCurrentPlayer.sockHTTP

       if length(FCurrentPlayer.iSessionId) < 5 then begin
          // pas loggé sur ogame
          TunnelSendFile(s, TUNNEL_GAME_FILE_NOT_LOGGED);
          exit;
       end;

       xPos := pos('/', Params);
       if xPos > 0 then begin
          subDir := copy(Params, 1, xPos - 1);

          if SameText(subDir, 'js') or SameText(subDir, 'css') or SameText(subDir, 'lang') or SameText(subDir, 'img') then begin
             // vérifie si il en existe une version en local
             sPageWeb := TunnelGetFullFile('game/' + Params);

             //////////////////////////////
             // TODO: Faire un système de telle sorte que l'on soit
             // prévenu si le fichier du serveur de jeu a changé

             if FileExists(sPageWeb) then begin
                // envoi le fichier
lCacheExist:
                OgameURLlw := tlgCalculETag(sPageWeb);

                if s.RequestIfNoneMatch <> '' then begin
                   if s.RequestIfNoneMatch = OgameURLlw then begin
                      s.MakeNonModified;
                      exit;
                   end;
                end;

                if OgameURLlw <> '' then begin
                   s.AddHeaderLigne('ETag: "' + OgameURLlw + '"');
                end;

                StatusSockets('GAME - Ressource locale: ' + sPageWeb);
                s.SendFile(sPageWeb, true);
                exit;
             end else begin
                // sera un cache automatique, donc on rajoute 'auto'
                bCanBeCached := true;
                sCachedFile  := TunnelGetFullFile('game/cache-auto/' + Params);

                ForceDirectories(ExtractFileDir(sCachedFile));

                // à présent on vérifie si le cache auto existe...
                if FileExists(sCachedFile) then begin
                   // vérifie la date

                   // FCurrDate
                   iDiff := FCurrDate - DateTimeToUnix(DateHeureCreationFichier1(sCachedFile));

                   if iDiff > (3600 * 24 * 2) then begin
                      // on met à jour le fichier
                      DeleteFile(sCachedFile);

                   end else begin
                      // on utilise la copie en cache
                      sPageWeb := sCachedFile;
                      bCanBeCached := false;
                      goto lCacheExist;
                   end;

                end;

             end;

          end;
          
       end;

       iPageType := 0;

       xPos := pos('page=', Params);
       if (xPos > 0) and (xPos < 100) then begin
          sPageWeb := copy(Params, xPos + 5, maxint);

          xPos := pos('&', sPageWeb);
          if xPos > 0 then begin
             System.Delete(sPageWeb, xPos, maxint);
          end;

          xPos := 0;

          // index.php?page=buildings&xtid&mode=Flotte

          if SameText(sPageWeb, 'allianzen') then begin
             // alliance
             if chkTunnelInterdirePageAlliance.Checked then begin
                xPos := 1;
             end;


          end else if SameText(sPageWeb, 'suche') then begin
             // recherche
             if chkTunnelInterdirePageRecherche.Checked then begin
                xPos := 1;
             end;

          end else if SameText(sPageWeb, 'buddy') then begin
             // liste d'amis
             if chkTunnelInterdirePageListeDamis.Checked then begin
                xPos := 1;
             end;

          end else if SameText(sPageWeb, 'options') then begin
             // options
             // chkTunnelInterdirePageOptions
             xPos := 1;

          end else if SameText(sPageWeb, 'renameplanet') then begin
             // renameplanet
             if chkTunnelInterdirePageSupprColonies.Checked then begin
                xPos := 1;
             end;
             
          end else if SameText(sPageWeb, 'flotten1') then begin
             iMiscActionOnThePage := 1;

          end else if SameText(sPageWeb, 'flotten2') then begin
             iMiscActionOnThePage := 2;

          end else if SameText(sPageWeb, 'flotten3') then begin
             iMiscActionOnThePage := 3;


          end else if SameText(sPageWeb, 'flottenversand') then begin
             // confirmation d'envoi de flotte
             // on réinitialise le rapport actuel
             FCurrentSocketTunnelRapport := nil;

             
          end else if SameText(sPageWeb, 'writemessages') then begin
             // écriture de message
             if chkTunnelInterdirePageEcritureMsg.Checked then begin
                xPos := 1;
             end;

          end else if SameText(sPageWeb, 'logout') then begin
             // écriture de message
             if chkTunnelInterdirePageLogout.Checked then begin
                xPos := 1;
             end;



          end else if SameText(sPageWeb, 'messages') then begin
             // lecture des messages, mais aussi SUPPRESSION de ceux-ci
             if chkTunnelInterdirePageSupprMsg.Checked then begin
                // si c'est une suprresion, il y a des données de postée

                if s.RequestPostedData <> '' then begin
                   // il y a des données postées
                   // on bloque la requete
                   xPos := 1;
                end;

             end;


          end else if SameText(sPageWeb, 'overview') then begin
             // page overview
             iPageType := CLASSTYPE_APPERCU;

          end;

          if xPos > 0 then begin
             TunnelSendFile(s, TUNNEL_GAME_FILE_PAGE_REFUSEE);
             exit;
          end;


       end;




       OgameURL   := FCurrentPlayer.iURLGameDir + sfcRemplace(Params, TUNNEL_GAME_SESSION_ID, 'session=' + FCurrentPlayer.iSessionId);
       OgameURLlw := lowercase(OgameURL);


       if (pos('pagead', OgameURLlw) > 0) or (pos('show_ad', OgameURLlw) > 0) then begin
          // pub google desactive
          s.MakeErreur(404);
          exit;
       end;

       if s.SocketRelay = nil then begin
          s.SocketRelay := THttpCli.Create(s);
       end;

       StatusSockets(OgameURL);
       if s.RequestPostedData <> '' then begin
          StatusSockets('Données: ' + s.RequestPostedData);
       end;

       // les cookies
       s.SocketRelay.Cookie := FCurrentPlayer.iCookies.GetCookieData;


       // UPDATE: Le lien de référence ne doit pas être n'importe quoi...
       // car cela représente alors un moyen de répérer les tricheurs


       // forcément http://serveur:xx/game/yyyy
       // ou
       // d'une page mais qui ne provient pas du jeu
       xPos := pos('/game/', s.RequestReferer);
       if xPos = 0 then begin
          if s.RequestReferer = '' then begin
             // le navigateur a désactivé les referer
             // on fait de même pour le tunnel
             oReferer := '';

          end else begin
             // sinon, le lien doit correspond à la page de choix des services
             oReferer := FCurrentPlayer.iURLGameDir;
          end;


       end else begin
          oReferer := FCurrentPlayer.iURLGameDir + copy(s.RequestReferer, xPos + length('/game/'), maxint);

       end;

       // le lien de référence:
       oReferer := sfcRemplace(oReferer, TUNNEL_GAME_SESSION_ID, 'session=' + FCurrentPlayer.iSessionId);

       s.SocketRelay.Reference := oReferer;




       suCopySocketHttpInfos(s.SocketRelay, FCurrentPlayer.sockHTTP);


       sPageWeb := FCurrentPlayer.myGETorPOST_InTamponX(OgameURL, s.RequestPostedData, s.SocketRelay);

       if s = nil then begin
          // ok, connexion fermée...
          exit;
       end;
       if s.SocketRelay = nil then begin
          exit;
       end;

       // met à jour les cookies...
       if s.SocketRelay.StatusCode >= 100 then
          FCurrentPlayer.iCookies.ParseHeader(s.SocketRelay.RcvdHeader);


       if iPageType > 0 then begin
          if length(sPageWeb) > 500 then begin
             if iPageType = CLASSTYPE_APPERCU then begin
                TunnelGetMoreDataForTunnel_Apercu(sPageWeb);


             end;
          end;
       end;


       sPageWeb := sfcRemplace(sPageWeb, 'session=' + FCurrentPlayer.iSessionId, TUNNEL_GAME_SESSION_ID);

       if chkTunnelUseRewritingRules.Checked then begin
          FRemplaceStrForPageWeb.Applique(sPageWeb);
       end;

       if (FCurrentSocketTunnelRapport <> nil) and (iMiscActionOnThePage > 0) then begin
          case iMiscActionOnThePage of
              1: begin
                  //iMiscActionOnThePage := FCurrentSocketTunnelRapport.Ressource.Metal + FCurrentSocketTunnelRapport.Ressource.Cristal + FCurrentSocketTunnelRapport.Ressource.Deuterium;
                  //iMiscActionOnThePage := iMiscActionOnThePage shr 1;

                  iMiscActionOnThePage := FCurrentPlayer.GetCapaciteDeFret(FCurrentSocketTunnelRapport.Ressource);

                  xBuffGT := sfcDivistionResultEnString(iMiscActionOnThePage, 24500, 2);

                  //sPageWeb := sfcRemplace(sPageWeb, '<input type="hidden" name="maxship203"', ' (' + xBuff + ')<input type="hidden" name="maxship203"');

                  iMiscActionOnThePage := Ceil(iMiscActionOnThePage / 24500);

                  if frac(iMiscActionOnThePage / 24500) > 0.7 then begin
                     Inc(iMiscActionOnThePage);
                  end;
                  sPageWeb := sfcRemplace(sPageWeb, '<input name="ship203" size="10" value="0"', format('<input name="ship203" size="10" value="%d"', [iMiscActionOnThePage]));



                  if FCurrentSocketTunnelRapport.RapportFullOri = '' then
                     FBase2DonneesRapports.LoadRapportDB(FCurrentSocketTunnelRapport);




                  // on doit remplacer le dernier form
                  // celui de flotten2

                  xPos := pos('flotten2', sPageWeb);

                  if xPos > 0 then begin

                     xPageTemp := copy(sPageWeb, 1, xPos);
                     System.Delete(sPageWeb, 1, xPos);


                     xBuff  := '</form>';
                     xBuff2 := '<tr><td colspan="4" class="c">Rapport sélectionné</th></tr>' +

                      '<tr><th colspan="2">' + FCurrentPlayer.GidToStr.GetGIDStr(203) + ' :</th><th colspan="2">' + xBuffGT + '</th></tr>' +

                      '<tr><th colspan="2">Score défense :</th><th colspan="2">' + IntToStr(FCurrentSocketTunnelRapport.DefenseScore) + '</th></tr>' +
                      '<tr><th colspan="2">Recycleur :</th><th colspan="2">' + sfcDivistionResultEnString(FCurrentSocketTunnelRapport.RecyclageNbRessource, 20000, 2) + '</th></tr>' +
                      '</form>';

                     sPageWeb := sfcRemplace(sPageWeb, xBuff, xBuff2);

                     sPageWeb := xPageTemp + sPageWeb;
                  end;


              end;
              2: begin

                  // on fait le parsing pour connaitre les coordonnées de la planète actuelle
                  xParser := TParsingFlotte2_ChoixDestination.Create(nil);

                  if xParser.ParseBuffer(sPageWeb) then begin
                     // ok, on modifie la page web maintenant
(*   <input name="galaxy" size="3" maxlength="2" onChange="shortInfo()" onKeyUp="shortInfo()" value="2" />
   <input name="system" size="3" maxlength="3" onChange="shortInfo()" onKeyUp="shortInfo()" value="361" />
   <input name="planet" size="3" maxlength="2" onChange="shortInfo()" onKeyUp="shortInfo()" value="6" />
   <select name="planettype" onChange="shortInfo()" onKeyUp="shortInfo()">
     <option value="1" >Planet </option>

  <option value="2" >DF </option>
  <option value="3" >Moon </option>
   </select>
   *)


                     xBuff  := format('<input name="galaxy" size="3" maxlength="2" onChange="shortInfo()" onKeyUp="shortInfo()" value="%d" />', [xParser.cHeader.Planete.Galaxie]);
                     xBuff2 := format('<input name="galaxy" size="3" maxlength="2" onChange="shortInfo()" onKeyUp="shortInfo()" value="%d" />', [FCurrentSocketTunnelRapport.PlaneteLocation.Galaxie]);
                     sPageWeb := sfcRemplace(sPageWeb, xBuff, xBuff2);

                     xBuff  := format('<input name="system" size="3" maxlength="3" onChange="shortInfo()" onKeyUp="shortInfo()" value="%d" />', [xParser.cHeader.Planete.SystemSolaire]);
                     xBuff2 := format('<input name="system" size="3" maxlength="3" onChange="shortInfo()" onKeyUp="shortInfo()" value="%d" />', [FCurrentSocketTunnelRapport.PlaneteLocation.SystemSolaire]);
                     sPageWeb := sfcRemplace(sPageWeb, xBuff, xBuff2);

                     xBuff  := format('<input name="planet" size="3" maxlength="2" onChange="shortInfo()" onKeyUp="shortInfo()" value="%d" />', [mbtGetRealPosition(xParser.cHeader.Planete.Position)]);
                     xBuff2 := format('<input name="planet" size="3" maxlength="2" onChange="shortInfo()" onKeyUp="shortInfo()" value="%d" />', [mbtGetRealPosition(FCurrentSocketTunnelRapport.PlaneteLocation.Position)]);
                     sPageWeb := sfcRemplace(sPageWeb, xBuff, xBuff2);

                     

                     if mbtIsLune(FCurrentSocketTunnelRapport.PlaneteLocation.Position) then begin
                        xBuff  := '<option value="3" >';
                        xBuff2 := '<option value="3" selected>';
                        sPageWeb := sfcRemplace(sPageWeb, xBuff, xBuff2);
                     end;

                  end;

                  xParser.Free;
              end;
              3: begin
                   // <input type="radio" name="order" value="1" >Attack<br />
                        xBuff  := '<input type="radio" name="order" value="1" >';
                        xBuff2 := '<input type="radio" name="order" value="1" checked>';
                        sPageWeb := sfcRemplace(sPageWeb, xBuff, xBuff2);
              end;  
          end;


          xBuff  := '</body>';
          xBuff2 := '<div align="center"><table width="519" border="0" cellpadding="0" cellspacing="1"><tr><td>' + sfcRemplace(FCurrentSocketTunnelRapport.RapportFullOri, #$0A, '<br>') + '</td></tr></div></body>';
          sPageWeb := sfcRemplace(sPageWeb, xBuff, xBuff2);


       end;

       OgameURLlw := tlgExtractLocation(s.SocketRelay.RcvdHeader);

       if OgameURLlw <> '' then begin
          // THttpCli met toujours les liens en mode URL complète
          // on doit aller chercher la location d'origine dans l'header
          if pos('http', OgameURLlw) = 1 then begin
             // on refuse la relocation
             // car on doit rester sur le serveur de jeu
             s.MakeErreur(404);
             exit;
          end;

          s.AddHeaderLigne('Location: ' + OgameURLlw);
       end;

       if s.SocketRelay.StatusCode < 100 then begin
          // erreur...
          s.MakeErreur(404);
          exit;
       end;

       s.SendPageWeb(sPageWeb, s.SocketRelay.StatusCode);

       if bCanBeCached and chkTunnelCache.Checked and (s.SocketRelay.StatusCode = 200) then begin
          WriteInThisFile(sCachedFile, sPageWeb);
          
       end;

    end;

    
end;

function TfrmRapportHistorique.TunnelGetFullFile(RelativePath: string): string;
begin
    Result := '';

    if pos('..', RelativePath) > 0 then begin
       exit;
    end;

    Result := sfcFileGetFullDir(FDossierTunnel, RelativePath);

    if pos(FDossierTunnel, Result) < 1 then begin
       // on est descendu dans la racine...
       // impossible car on a interdit la chaine ".." mais bon, peut-être
       // le code hexadécimal a été utilisé
       Result := '';
       exit;
    end;

end;




procedure TfrmRapportHistorique.TunnelSendFile(s: TTunnelHttpConnection; RelativePath: string);
var Fichier: string;
begin

    Fichier := TunnelGetFullFile(RelativePath);

    if Fichier = '' then begin
       s.MakeErreur(404);
       exit;
    end;

    s.SendFile(Fichier, true);
end;


procedure TfrmRapportHistorique.DoOnRequest(Sender: TObject);
label lSelectionPage, lSectionNoSession;
var s: TTunnelHttpConnection;
    sServiceDesire, sParams: string;
    tid: PTunnelSessionId;
    xPos: integer;
    CurrDate: int64;
begin

   s := TTunnelHttpConnection(Sender);

   //StatusSockets(s.RequestMethod + ' ' + s.RequestVersion + ' (ContentLength: ' + IntToStr(s.RequestContentLength) + ')');
   //StatusSockets('Req: ' + s.RequestPath);

   //StatusSockets('Cookies: ' + s.RequestCookies);



   //Status(s.RequestCookies);

   CurrDate := DateTimeToUnix(Now);

   tid := FTunnelSessionId.Get_Pointeur(s.GetRequestCookie(TUNNEL_COOKIE_AUTH_SESSION_ID));

   s.SessionId := tid;





   sServiceDesire := '';
   sParams        := '';

   if length(s.RequestPath) > 4 then begin
      sServiceDesire := s.RequestPath;
      System.Delete(sServiceDesire, 1, 1);

      xPos := pos('/', sServiceDesire);
      if xPos > 1 then begin
         sParams := copy(sServiceDesire, xPos + 1, maxint);
         System.Delete(sServiceDesire, xPos, maxint);
      end;

   end;





   if tid = nil then begin
      // affiche la page de login
lSectionNoSession:
      xPos := 1;

      if SameText(sServiceDesire, 'relay') then begin
         TunnelTraitement_RELAY(s, sParams);
         xPos := 0;

      end else if SameText(sServiceDesire, 'forum') then begin
         s.MakeRedirection('/');

      end else if SameText(sServiceDesire, 'robot') then begin
         s.MakeRedirection('/');

      end else if SameText(sServiceDesire, 'game') then begin
         s.MakeRedirection('/');

      end else if sServiceDesire <> '' then begin
         // dossier img ou css ou autres
         TunnelSendFile(s, s.RequestPath);
         xPos := 0;
      end;

      if xPos = 1 then begin

         MotorTemplate.LoadFromFile(TunnelGetFullFile(TUNNEL_RELAY_FILE_LOGIN_PAGE));
         MotorTemplate.ConditionSet(TPL_COND_LOGINPAGE_PASSWORD_INVALID, 0);
         MotorTemplate.ProceedFinal;

         s.MakeNoCache;

         if MotorTemplate.DocumentOut <> '' then begin
            s.SendPageWeb(MotorTemplate.DocumentOut);
         end else begin
            s.MakeErreur(404);
         end;

         MotorTemplate.Clear;


      end;


   end else begin
      if tid.DateExp < CurrDate then begin
         // expiré
         tid := nil;
         goto lSectionNoSession;

         exit;
      end;


      //  /game/xxxx
      //  /forum/xxxxx
      //  /robot/xxxx
      //  /relay/xxxx
      if sServiceDesire = '' then begin
         // affiche la page de sélection
lSelectionPage:
         TunnelSendFile(s, TUNNEL_RELAY_FILE_SELECTION_SERVICE);


      end else begin

         if SameText(sServiceDesire, 'game') then begin
            TunnelTraitement_GAME(s, sParams);
            
         end else if SameText(sServiceDesire, 'forum') then begin
            TunnelTraitement_FORUM(s, sParams);

         end else if SameText(sServiceDesire, 'robot') then begin
            TunnelTraitement_ROBOT(s, sParams);

         end else if SameText(sServiceDesire, 'relay') then begin
            TunnelTraitement_RELAY(s, sParams);

         end else begin
            // dossier img ou css ou autres
            TunnelSendFile(s, s.RequestPath);

         end;

      end;

   end;


  // s.SendPageWeb('yeah baby procedure tabProfilsEditExit(Sender: TObject);' +
  //     'procedure TfrmRapportHistorique.DoOnRequest(Sender: TObject);');

end;



procedure TfrmRapportHistorique.cmdTunnelLancerClick(Sender: TObject);
var i: integer;
    sFormat, sURL: string;
begin
      cmdTunnelStopClick(nil);
      cmdTunnelLancer.Enabled := false;

      // LocalIPList.Count


      with wssTunnel do begin
         Banner        := '';              // Pas de message de bienvenue lors de la connexion sur le serveur
         BannerTooBusy := '';              // Idem
         ClientClass  := TTunnelHttpConnection;

         if chkTunnelRestreindreLocal.Checked then begin
            Addr := '0.0.0.0';
         end else begin
            Addr := '0.0.0.0';
         end;

         Port := seTunnelPort.Text;

         StatusSockets(format(_('Tunnel - Lancement du serveur - Port %s'), [Port]));

         try
            Listen;
            txtTunnelURL.Text := 'http://127.0.0.1';



            if seTunnelPort.Value <> 80 then begin
               txtTunnelURL.Text := txtTunnelURL.Text + ':' + seTunnelPort.Text;
               sFormat := 'http://%s' + ':' + seTunnelPort.Text + '/';

            end else begin
               sFormat := 'http://%s/';
            end;

            if LocalIPList.Count > 0 then begin
               for i := 0 to LocalIPList.Count - 1 do begin
                   sURL := format(sFormat, [LocalIPList.Strings[i]]);
                   
                   StatusSockets(format(_('URL Possible: %s'), [sURL]));

               end;

            end;

            txtTunnelURL.Text := txtTunnelURL.Text + '/';
            seTunnelPort.Enabled := false;

         except
            StatusSockets(_('Tunnel - Echec d''écoute. Le serveur est peut-être déjà lancé'));
            cmdTunnelLancer.Enabled := true;
         end;
      end;


      cmdTunnelStop.Enabled := true;
      

      FRemplaceStrForPageWeb.Clear;
      if chkTunnelUseRewritingRules.Checked then begin
         FRemplaceStrForPageWeb.LoadFromFile(FDossierHTML + 'game_global_rules.ini');
      end;



end;

procedure TfrmRapportHistorique.cmdTunnelStopClick(Sender: TObject);
var i : integer;
begin
    StatusSockets(_('Tunnel - Fermeture du serveur'));
    wssTunnel.Close;

    if wssTunnel.ClientCount > 0 then begin
       StatusSockets(format(_('Tunnel - Fermeture des connexions actives (%d)'), [wssTunnel.ClientCount]));

       for i := wssTunnel.ClientCount - 1 downto 0 do
          wssTunnel.Client[i].Close;

    end;
    cmdTunnelLancer.Enabled := true;
    seTunnelPort.Enabled := true;

    txtTunnelURL.Text := _('Tunnel non activé');
end;


procedure TfrmRapportHistorique.cmdTunnelSwitchClick(Sender: TObject);
   procedure SwitchIt(Valeur: boolean);
   begin
      chkTunnelInterdirePageAlliance.Checked      := Valeur;
      chkTunnelInterdirePageRecherche.Checked     := Valeur;
      chkTunnelInterdirePageEcritureMsg.Checked   := Valeur;
      chkTunnelInterdirePageSupprMsg.Checked      := Valeur;
      chkTunnelInterdirePageSupprColonies.Checked := Valeur;

      chkTunnelInterdirePageListeDamis.Checked := Valeur;
   end;

begin

   SwitchIt(NoT(chkTunnelInterdirePageAlliance.Checked));

end;

procedure TfrmRapportHistorique.timAdditionnalTimer(Sender: TObject);
begin

    Status('Operation adv...');

    timAdditionnal.Interval := 0;


    if FLocalSetting.SettingFileVersion = CNT_CURRENT_SETTING_VERSION then begin
       chkTunnelLancerAuDem.Checked       := FLocalSetting.ConfGetBool(CNT_LOCALSETTING_BOOL_TunnelLoadAtStartup);
       chkTunnelUseRewritingRules.Checked := FLocalSetting.ConfGetBool(CNT_LOCALSETTING_BOOL_TunnelUseRegleReecriture);
       chkTunnelRestreindreLocal.Checked  := FLocalSetting.ConfGetBool(CNT_LOCALSETTING_BOOL_TunnelRestreindreLocal);
       chkTunnelDesactiveCompressionIE.Checked  := FLocalSetting.ConfGetBool(CNT_LOCALSETTING_BOOL_TunnelDesactiveCompressionIE);

    end else begin
       FLocalSetting.ConfSetBool(CNT_LOCALSETTING_BOOL_TunnelLoadAtStartup, false);
       FLocalSetting.ConfSetBool(CNT_LOCALSETTING_BOOL_TunnelUseRegleReecriture, true);
       FLocalSetting.ConfSetBool(CNT_LOCALSETTING_BOOL_TunnelRestreindreLocal, true);
       FLocalSetting.ConfSetBool(CNT_LOCALSETTING_BOOL_TunnelDesactiveCompressionIE, true);

    end;


    Global_DontUseCompressionIE :=  chkTunnelDesactiveCompressionIE.Checked;

    FLocalSetting.LoadFromFile('', lsoIniData);

    txtTunnelRootUser.Text := FLocalSetting.IniTunnelRootUser;
    txtTunnelRootPass.Text := FLocalSetting.IniTunnelRootPass;

    if txtTunnelRootUser.Text = '' then
       txtTunnelRootUser.Text := 'root';

    txtForumUsername.Text := FLocalSetting.IniTunnelForumUser;
    txtForumPassword.Text := FLocalSetting.IniTunnelForumPass;

    //Status(iaEncode64URL(txtForumUsername.Text + ':' + txtForumPassword.Text) + '==');



    if Global_LocalSetting.ConfGetBool(CNT_LOCALSETTING_BOOL_TunnelLoadAtStartup) then begin
       cmdTunnelLancerClick(nil);
    end;

    Status('Operation adv end');

end;

procedure TfrmRapportHistorique.seTransportMassifHumanIntervalleMinChange(
  Sender: TObject);
begin
   lblTransportMassifInfos.Caption := format(_('%d à %d secondes'), [seTransportMassifHumanIntervalleMin.Value, seTransportMassifHumanIntervalleMin.Value + seTransportMassifHumanComplHuman.Value]);

end;

procedure TfrmRapportHistorique.seTunnelPortExit(Sender: TObject);
begin
    FLocalSetting.ConfSet(CNT_LOCALSETTING_TunnelPort, seTunnelPort.Value);
end;

procedure TfrmRapportHistorique.chkTunnelLancerAuDemClick(Sender: TObject);
begin
    FLocalSetting.ConfSetBool(CNT_LOCALSETTING_BOOL_TunnelLoadAtStartup, chkTunnelLancerAuDem.Checked);
end;

procedure TfrmRapportHistorique.chkTunnelUseRewritingRulesClick(
  Sender: TObject);
begin
    FLocalSetting.ConfSetBool(CNT_LOCALSETTING_BOOL_TunnelUseRegleReecriture, chkTunnelUseRewritingRules.Checked);
end;

procedure TfrmRapportHistorique.chkTunnelRestreindreLocalClick(Sender: TObject);
begin
    FLocalSetting.ConfSetBool(CNT_LOCALSETTING_BOOL_TunnelRestreindreLocal, chkTunnelRestreindreLocal.Checked);
end;

procedure TfrmRapportHistorique.txtTunnelRootUserExit(Sender: TObject);
begin
    FLocalSetting.IniTunnelRootUser := txtTunnelRootUser.Text;
end;

procedure TfrmRapportHistorique.txtTunnelRootPassExit(Sender: TObject);
begin
    FLocalSetting.IniTunnelRootPass := txtTunnelRootPass.Text;
end;

procedure TfrmRapportHistorique.txtForumUsernameExit(Sender: TObject);
begin
    FLocalSetting.IniTunnelForumUser := txtForumUsername.Text;
end;

procedure TfrmRapportHistorique.txtForumPasswordExit(Sender: TObject);
begin
    FLocalSetting.IniTunnelForumPass := txtForumPassword.Text;
end;

procedure TfrmRapportHistorique.cmdTunnelGoClick(Sender: TObject);
begin
    Clipboard.AsText := txtTunnelURL.Text;
end;

procedure TfrmRapportHistorique.chkTunnelDesactiveCompressionIEClick(
  Sender: TObject);
begin
    FLocalSetting.ConfSetBool(CNT_LOCALSETTING_BOOL_TunnelDesactiveCompressionIE, chkTunnelDesactiveCompressionIE.Checked);
    Global_DontUseCompressionIE := chkTunnelDesactiveCompressionIE.Checked;

end;

procedure TfrmRapportHistorique.optExportOGSpy302Click(Sender: TObject);
begin
    optExportSQLUpdate.Enabled := false;
    optExportSQLInsert.Enabled := false;
    optExportSQLReplace.Checked := true;
end;

procedure TfrmRapportHistorique.optExportOGSpyClick(Sender: TObject);
begin
    optExportSQLUpdate.Enabled := true;
    optExportSQLInsert.Enabled := true;
end;

procedure TfrmRapportHistorique.menActionToutEffacerClick(Sender: TObject);
begin
    if FCurrPlayerCurrPlanete = nil then exit;

    if FLastLigneSelectPlaneteScript > 0 then begin
       FCurrPlayerCurrPlanete.cActions.Clear;

       // Met à jour l'affichage
       AfficheActionInGrid(sgElementsAction, FCurrPlayerCurrPlanete.cActions);
    end;
end;

procedure TfrmRapportHistorique.menAjouterListeDattaqueClick(Sender: TObject);
var TotalRessource: integer;

    myLA   : PLAItem;
    spOrder: PLAActionOrdreAttaquer;

    fraction: single;
begin

    if FCurrentRapport = nil then exit;

    FCurrDate := DateTimeToUnix(Now);


    New(myLA);


    //
    // Définit l'opération
    //

    myLA.Operation.Cible.Galaxie       := FCurrentRapport.PlaneteLocation.Galaxie;
    myLA.Operation.Cible.SystemSolaire := FCurrentRapport.PlaneteLocation.SystemSolaire;

    if mbtIsLune(FCurrentRapport.PlaneteLocation) then begin
       myLA.Operation.Cible.Position := mbtGetRealPosition(FCurrentRapport.PlaneteLocation.Position);
       myLA.Operation.CibleType      := ctLune;

    end else begin
       myLA.Operation.Cible.Position := FCurrentRapport.PlaneteLocation.Position;
       myLA.Operation.CibleType      := ctPlanete;
    end;

    myLA.Operation.Vitesse := 10;
    myLA.Operation.Ordre   := ooAttaquer;
    myLA.Operation.Ressources.Metal     := 0;
    myLA.Operation.Ressources.Cristal   := 0;
    myLA.Operation.Ressources.Deuterium := 0;






    //////////////////////////////////////////
    // Définit les champs additionnels de l'ordre attaquer
    //////////////////////////////////////////

    New(spOrder);

    // Nombre de GT pour récupérer toute les ressources possible
    TotalRessource := FCurrentRapport.Ressource.Metal + FCurrentRapport.Ressource.Cristal + FCurrentRapport.Ressource.Deuterium;


    spOrder.RessourceMin       := TotalRessource;
    spOrder.DefenseScoreMax    := FCurrentRapport.DefenseScore;
    spOrder.RecyclageNbRessourceMax  := FCurrentRapport.RecyclageNbRessource;


   

    //////////////////////////////////////////
    // définit les informations de sondage
    //////////////////////////////////////////

    spOrder.Sondage.Planete := SpiderGalaxieGetSelectedPlanete;
    spOrder.Sondage.DureePourAtteindreLaCible := 0;

    if chkLASondageAvantAttackActive.Checked then begin
       spOrder.Sondage.DoAvantAttaque := 1;
    end else begin
       spOrder.Sondage.DoAvantAttaque := 0;
    end;
    spOrder.Sondage.DoAvantImpact  := 0;

    spOrder.Sondage.Status         := lassIdle;

    if sfcFlagsIsIn(FLAG_NIV_ESP_ELEVE, FCurrentRapport.Flags) then begin
       spOrder.Sondage.NbSondes       := FCurrentPlayer.Conf.SondesNbNivEsp;
    end else begin
       spOrder.Sondage.NbSondes       := FCurrentPlayer.Conf.SondesNbMini;
    end;

    spOrder.Sondage.FlotteImpactDate := 0;
    spOrder.Sondage.FlotteLaunchDate := 0;
    spOrder.Sondage.NextRapportChecking := 0;


    //////////////////////////////////////////
    // définit la liste des vaisseaux
    //////////////////////////////////////////


    // On ne peut prendre au maximum la moitié des ressources
    //TotalRessource := TotalRessource shr 1;

    TotalRessource := FCurrentPlayer.GetCapaciteDeFret(FCurrentRapport.Ressource) ;


    // Obtient le nombre de GT
    FNbGTForCurrentRapport := Ceil(TotalRessource / 24500);
    FNbPTForCurrentRapport := Ceil(TotalRessource / 4900);

    // défini la partie fractionnaire
    fraction := seLAPartieDecimale.Value / 100;

    if frac(TotalRessource / 24500) > fraction then begin
       Inc(FNbGTForCurrentRapport);
    end;
    if frac(TotalRessource / 4900) > fraction then begin
       Inc(FNbPTForCurrentRapport);
    end;


    // initialise la liste des vaisseaux
    mlaviInitListeP(@myLA.Vaisseaux);

    if chkLAVersionPT.Checked then begin
       // PT
       mlaviAddVaisseaux(@myLA.Vaisseaux, 202, FNbPTForCurrentRapport + seLAVaisseauxSuppl.Value);

    end else begin
       // GT
       mlaviAddVaisseaux(@myLA.Vaisseaux, 203, FNbGTForCurrentRapport + seLAVaisseauxSuppl.Value);
    end;


    // ajoute les vaisseaux de combat si nécessaire
    if chkLAInclureCroiseurs.Checked then begin
       mlaviAddVaisseaux(@myLA.Vaisseaux, 206, seLANbCroiseurs.Value);
    end;
    if chkLAInclureVB.Checked then begin
       mlaviAddVaisseaux(@myLA.Vaisseaux, 207, seLANbVB.Value);
    end;


    //
    // Défini le recalcul des GT à utiliser
    //

    spOrder.VaisseauxAjustement.AutoAjustActive := chkRecalculVaisseauxAvantAttaque.Checked;
    spOrder.VaisseauxAjustement.FractionMajoration  := fraction;
    spOrder.VaisseauxAjustement.AjoutSupplementaire := seLAVaisseauxSuppl.Value;
    spOrder.VaisseauxAjustement.PTVersion       := chkLAVersionPT.Checked;



    //
    // Associe les champs additionnels à l'opération
    //

    myLA.ActionOrdreType := laatAttaquer;
    myLA.ActionOrdre     := spOrder;






    //
    // initialise les autres champs
    //

    myLA.DateCanPrisEnCompte := 0;
    myLA.DateEffecue         := 0;
    myLA.NePasExecuterAvant  := 0;

    
    myLA.Depart := SpiderGalaxieTextPlaneteToLocation(cbAttaquePlanete.Text);


    FCurrentPlayer.cListeDattaque.Add(myLA);

    
    // met à jour la grille
    sggUpdateListeAttaque(sgListeAttaque, FCurrentPlayer);



    if chkLAMettreAJourDateAttaque.Checked then begin


       if mrInjectOnlyIfNeed(FCurrentRapport.DateLastAttaque, FCurrDate) then begin
          Status('Liste d''attaque -> Nombre d''attaque mis à jour - ' + mbtPlanetLocationToStr(FCurrentRapport.PlaneteLocation));
          FCurrentRapport.NbAttack := FCurrentRapport.NbAttack + 1;
          FCurrentRapport.bShouldBeUpdateFixed := true;

          seNbAttaque.Value := FCurrentRapport.NbAttack;
          cmdUpdatePlaneteClick(nil);
       end;

    end;

    Status(_('Ajouté à la liste d''attente'));

end;

procedure TfrmRapportHistorique.optExportGalaxyToolClick(Sender: TObject);
begin
    optExportSQLUpdate.Enabled := true;
    optExportSQLInsert.Enabled := true;
end;

procedure TfrmRapportHistorique.chkSondageInclureLuneClick(Sender: TObject);
begin
    if chkSondageInclureLune.Checked then begin
       chkSondageAddOnlyLune.Checked := false;
    end;

end;

procedure TfrmRapportHistorique.chkSondageAddOnlyLuneClick(Sender: TObject);
begin
    if chkSondageAddOnlyLune.Checked then begin
       chkSondageInclureLune.Checked := false;
    end;
end;

procedure TfrmRapportHistorique.menFiltresLuneAfficheOnlyClick(Sender: TObject);
begin
   FCurrentPlayer.Conf.FiltreLuneState  := CNT_FILTRE_LNE_STATE_LUNE_SEULEMENT;
   RefreshMenuFiltreCheckbox;
end;

procedure TfrmRapportHistorique.menFiltresLuneExclureClick(Sender: TObject);
begin
   FCurrentPlayer.Conf.FiltreLuneState  := CNT_FILTRE_LNE_STATE_EXCLURE;
   RefreshMenuFiltreCheckbox;
end;

procedure TfrmRapportHistorique.menFiltresLuneInclureClick(Sender: TObject);
begin
   FCurrentPlayer.Conf.FiltreLuneState  := CNT_FILTRE_LNE_STATE_INCLURE;
   RefreshMenuFiltreCheckbox;
end;

procedure TfrmRapportHistorique.menExporterempire1Click(Sender: TObject);
var List: TStringList;
begin

   List := TStringList.Create;
   List.Capacity := 40;
   FCurrentPlayer.ExportEmpireToText(List, FGidToStr);

   Clipboard.AsText := List.Text;

   txtDBPlanetes.Lines.Add('----------------------');

   txtDBPlanetes.Lines.Add('Les données ont été copié dans le presse papier');
   txtDBPlanetes.Lines.Add('');

   txtDBPlanetes.Lines.AddStrings(List);

   List.Free;

   pcSwitch.ActivePageIndex := tabOutils.PageIndex;
   pcOutils.ActivePageIndex := tabOutilsPlanetes.PageIndex;

end;

procedure TfrmRapportHistorique.menSondageEnleverJoueurClick(Sender: TObject);
var i: integer;
    pePlanete, peTest: PGalaxiePlanete;
    peTestSd: PPlaneteASonder;
    NbDel: integer;
begin


    NbDel := 0;

    if FCurrentSondageSel <> nil then begin

       pePlanete := FBase2DonneesPlanete.Get_Pointeur(FCurrentSondageSel.Coord);

       i := FCurrentPlayer.SondagePlanetesList.IndexOf(FCurrentSondageSel);
       FCurrentPlayer.SondagePlanetesList.Delete(i);


       if pePlanete <> nil then begin
          pePlanete.Joueur;

          for i := FCurrentPlayer.SondagePlanetesList.Count - 1 downto 0 do begin
             peTestSd := FCurrentPlayer.SondagePlanetesList.Items[i];

             peTest := FBase2DonneesPlanete.Get_Pointeur(peTestSd.Coord);

             if peTest <> nil then begin
                if SameText(peTest.Joueur, pePlanete.Joueur) then begin
                   // on l'enlève
                   FCurrentPlayer.SondagePlanetesList.Delete(i);
                   Inc(NbDel);
                end;

             end;

          end;


       end;

       // met à jour la liste
       UpdateSondages(sgSondages);
    end;


end;

procedure TfrmRapportHistorique.sgChampDeRuinesClickCell(Sender: TObject; ARow,
  ACol: Integer);
var i: integer;
    peRapport: PRapportHead;
    peGalaxy: PGalaxiePlanete;
begin

    // gbPlanete
    i := ARow - 1;

    if FChampDeRuineList = nil then exit;
    if (i < 0) or (i >= FChampDeRuineList.Count) then exit;

    peGalaxy := FChampDeRuineList.Items[i];


    // quand il y a trop d'élément, pour accélerer les recherches, on utilise
    // la base de données d'élément filtrés
    if FBase2DonneesRapports.Count < 1000 then begin
       peRapport := FBase2DonneesRapports.Get_Pointeur(peGalaxy.Location);
    end else begin
       peRapport := FBaseFiltree.Get_Pointeur(peGalaxy.Location);
    end;



    if peRapport <> nil then begin
       FCurrentRapport := peRapport;
       LoadCurrentInForm;
       
    end else begin
       FCurrentRapport := nil;
       InitForm;
    end;

end;

procedure TfrmRapportHistorique.sgElementsActionSelectCell(Sender: TObject;
  ACol, ARow: Integer; var CanSelect: Boolean);
begin
    FLastLigneSelectPlaneteScript   := ARow;
    //FLastColonneSelectPlaneteScript := ACol;
end;

procedure TfrmRapportHistorique.sgElementsConstructibleClickCell(
  Sender: TObject; ARow, ACol: Integer);
var i, k: integer;
    cE: POGItemCost;
    lProduction: TList;
    TempRestante: integer;
    xResultat: TResultatBestProd;

    pxOpt: POGResUsed;
begin
    FLastLigneSelectedInConstruction := ARow;
    menConstructionVoirOptimisation.Enabled := false;

    if FCurrPlayerCurrPlanetForConstruction = nil then begin
       exit;
    end;

    // Ajoute l'élément dans l'action manager
    if FLastLigneSelectedInConstruction > 0 then begin
       // les deux premières lignes correspondant aux ressources et à la production
       i := FLastLigneSelectedInConstruction - 3;

       if i >= FCurrPlayerCurrPlanetForConstruction.cElements.Count then exit;
       if i < 0 then begin
          exit;
       end;

       cE := FCurrPlayerCurrPlanetForConstruction.cElements.Items[i];

       k := GetTypeOfGID(cE.GID);

       if (k <> CNT_ITEM_DESIGN_BATIMENT) and (k <> CNT_ITEM_DESIGN_RECHERCHE) then begin
          // non géré
          exit;
       end;

       if cE.CanBeBuildIn <= 0  then begin
          // déjà constructible
          // ou
          // impossible à optimiser
          exit;
       end;

       menConstructionVoirOptimisation.Enabled := true;
    end;


end;

procedure TfrmRapportHistorique.sgElementsConstructibleDblClickCell(Sender: TObject; ARow,
  ACol: Integer);
var cE: POGItemCost;
    cA: TElementActionItem;
    i, k: integer;
begin

    if FCurrPlayerCurrPlanetForConstruction = nil then exit;

    // Ajoute l'élément dans l'action manager
    if ARow > 0 then begin
       // les deux premières lignes correspondant aux ressources et à la production
       i := ARow - 3;

       if i >= FCurrPlayerCurrPlanetForConstruction.cElements.Count then exit;
       if i < 0 then begin
          exit;
       end;

       cE := FCurrPlayerCurrPlanetForConstruction.cElements.Items[i];

       k := GetTypeOfGID(cE.GID);

       if (k <> CNT_ITEM_DESIGN_BATIMENT) and (k <> CNT_ITEM_DESIGN_RECHERCHE) then begin
          // non géré
          exit;
       end;


       cA.GID           := cE.GID;
       cA.Quantite      := 1;
       cA.Status        := ACTION_STATUS_ENATTENTE;
       cA.NiveauRequis  := -1;
       cA.DateDone      := 0;
       cA.NiveauAtteint := 0;

       FCurrPlayerCurrPlanetForConstruction.cActions.Add(cA);

       AfficheActionInGrid(sgElementsAction, FCurrPlayerCurrPlanetForConstruction.cActions);
    end;

end;

procedure TfrmRapportHistorique.cmdCheckForFastEvacuationClick(Sender: TObject);
var xWhere: TOGDestinationType;
    Cible: TPlanetLocation;
    xOrdre: TOGOrdre;
    Resultat: TFlotteEnvoiRes;

    timeStart: longword;

    xSpeed: integer;
begin

    cmdCheckForFastEvacuation.Enabled := false;

    timeStart := GetTickCount;

    Cible.Galaxie       := seFastEvaGalaxy.Value;
    Cible.SystemSolaire := seFastEvaSystem.Value;
    Cible.Position      := seFastEvaPosition.Value;

    if (Cible.Galaxie < 1) then begin
       lblStatusAttaque.Caption := _('Cible invalide');
       exit;
    end;

     if chkFastEvacuationToMoon.Checked then begin
        xWhere := ctLune;

     end else if chkFastEvacuationToDebris.Checked then begin
        xWhere := ctRuines;

     end else begin
        xWhere := ctPlanete;
     end;

     // optFastEvaOrdre
     if optFastEvaOrdreAttaquer.Checked then begin
        xOrdre := ooAttaquer;

     end else if optFastEvaOrdreTransporter.Checked then begin
        xOrdre := ooTransport;

     end else if optFastEvaOrdreExploiter.Checked then begin
        xOrdre := ooExploiter;

     end else if optFastEvaOrdreStationner.Checked then begin
        xOrdre := ooBaser;

     end else begin
        xOrdre := ooTransport;

     end;

     if cbFastEvaSpeed.ItemIndex < 0 then begin
        // 10% par défaut
        cbFastEvaSpeed.ItemIndex := 9;
     end;

     // Variation de 1 à 10 pour la vitesse
     xSpeed := 10 - cbFastEvaSpeed.ItemIndex;

     Resultat := FCurrentPlayer.ProceedFastEvacuation(Cible, xSpeed, xWhere, seFastEvacuationNbVaisseaux.Value, xOrdre);

     case Resultat of
        ferFatalError:  lblFastEvaStatus.Caption := _('Fatal Error');
        ferSocketError: lblFastEvaStatus.Caption := _('Socket erreur');
        ferShouldRetry: lblFastEvaStatus.Caption := _('Doit re-essayer (erreur)');
        ferShouldRetryButNotError: lblFastEvaStatus.Caption := _('Doit re-essayer');
        ferSuccess: lblFastEvaStatus.Caption := _('Reussi');
        ferNoVaisseaux: lblFastEvaStatus.Caption := _('Pas de vaisseaux');
        ferFlotteMaxAtteinte: lblFastEvaStatus.Caption := _('Max flotte atteint');
        ferNotOrReLoginCertain: lblFastEvaStatus.Caption := _('Doit se relogger');
        ferPlaneteInvalid: lblFastEvaStatus.Caption := _('Planete invalide');
     end;

     timeStart := GetTickCount - timeStart;

     Status('Durée: ' + IntToStr(timeStart) + ' ms');

    cmdCheckForFastEvacuation.Enabled := true;

end;

procedure TfrmRapportHistorique.cmdInternalStateClick(Sender: TObject);
begin
   if FCurrentPlayer <> nil then begin
      FCurrentPlayer.ShowInternal;

   end else begin
      Status('Inexistant');
   end;

end;

end.
